2017-02-14 6 views
0

Я пытаюсь построить компонент дерева, где компонент od-tree-node вложен рекурсивно для создания дочерних узлов. У меня проблемы с обработкой событий. Для событий щелчка на листовом узле событие мыши всегда запускается так, как если бы событие произошло в верхней части самого компонента. Я не уверен, как справиться с этим.Как обрабатывать события во вложенном рекурсивном компоненте

Ожидаемое поведение. Когда пользователь нажимает на лист/родительский/корневой узел, родительский компонент (например: app.component.ts) должен знать, какой узел был нажат.

Текущее поведение: Независимо от того, какой узел щелкнул, корневой узел выбран (испускается родительский компонент)

plunker: https://plnkr.co/edit/JZTlA5?p=preview

Здесь нет шаблона:

node.component .html

<!-- parent node --> 
<label [attr.for]="resource.resourceType" [class]="cssClasses" *ngIf="resource.hasChildren()" [hidden]="matchedChildrenCount(search, resource) === 0"> 
    <a (click)="toggleNode($event)"> <i [class]="getNodeStateIcon()"></i></a> 
    <input type="checkbox" *ngIf="showCheckboxes" [checked]="selected"> 
    <a [title]="resource.resourceName" (click)="selectNode($event);"> 
     <i [class]="resource.getIcon()"></i> {{resource.resourceName}} | {{ matchedChildrenCount(search, resource) | lpad : 2 : '0'}} 
    </a> 
</label> 
<!-- leaf node --> 
<label [attr.for]="resource.resourceType" [class]="cssClasses" *ngIf="!resource.hasChildren()" [hidden]="!isMatched(search, resource)"> 
    <input type="checkbox" *ngIf="showCheckboxes" [checked]="selected"> 
    <a [title]="resource.resourceName" (click)="selectNode($event);"> 
     <i class="icon-status-indicator"></i> {{resource.resourceName}} 
     <div class="group" *ngIf="resource?.group !== 'Default'">{{resource.group}}</div> 
    </a> 
</label> 
<!-- recrusive child nodes --> 
<ul *ngIf="resource.expanded"> 
    <li *ngFor="let child of resource?.children"> 
    <od-tree-node 
     [resource]="child" 
     [search]="search" 
     (selected)="selectNode($event)" 
     ></od-tree-node> 
    </li> 
</ul> 

node.component.ts

@Component({ 
    moduleId: module.id, 
    selector: 'od-tree-node', 
    templateUrl: 'node.component.html', 
    styleUrls: ['node.component.css'], 
    changeDetection: ChangeDetectionStrategy.OnPush 
}) 
export class NodeComponent implements OnInit, OnChanges, OnDestroy { 
    @Input() resource: TreeNode; 

    @Output() selected = new EventEmitter<TreeNode>(); 

    cssClasses: string; 

    /** 
    * select/unselect node 
    * 
    */ 
    selectNode(event: MouseEvent) { 
    if(event instanceof MouseEvent) { 
     event.preventDefault(); 
     event.stopPropagation(); 
     } 
    this.resource.selected = true; 
    this.cssClasses = this.setCssClasses(); 
    this.selected.emit(this.resource); 
    } 
... 
.... 
.... 
} 
+0

Вы говорите, что 'event.stopPropagation()' не работает? – AngularChef

+0

Да. Я действительно в тупике. – Sudhakar

+0

Действительно ли проверка 'if (event instanceof MouseEvent)' необходима? – AngularChef

ответ

3

В вашем случае каждый узел отправляет себя своему родителю и, таким образом, приложение компонент всегда получить корневой узел дерева. Решение заключается в том, что в случае события клика отправьте сам этот узел в родительский узел, просто передайте то, что получено от eventemitter дочернего узла.

selectNode(event: MouseEvent) { 
    console.log(event) 
    let selNode: any; 
    if(event instanceof MouseEvent) { 
         event.preventDefault(); 
         event.stopPropagation(); 
         selNode = this.resource 
    } else { 
     selNode = event 
    } 
    this.selected.emit(selNode); 
} 
+0

Спасибо! это именно то, что я хотел. – Sudhakar