【问题标题】:how to handle events in nested recursive component如何处理嵌套递归组件中的事件
【发布时间】:2017-02-16 01:45:33
【问题描述】:

我正在尝试构建一个树组件,其中 od-tree-node 组件递归嵌套以构建子节点。我在处理事件时遇到问题。 对于叶节点上的单击事件,鼠标事件总是触发,就好像事件发生在最顶部的组件上一样。我不确定如何处理。

预期行为:当用户点击叶子/父/根节点时,父组件(例如:app.component.ts)需要知道点击了哪个节点。

当前行为:无论点击哪个节点,都选择根节点(发射到父组件)

plunkerhttps://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);
  }
 ...
 ....
 ....
}

【问题讨论】:

  • 你是说event.stopPropagation() 不起作用?
  • 是的。我真的很难过。
  • if(event instanceof MouseEvent) 测试真的有必要吗?
  • 是的,我添加是因为有问题。由于嵌套模板,selected 事件由于事件冒泡而获取 TreeNode 组件而不是 MouseEvent 对象
  • 老实说,我不知道你期待什么。您的 selectNode() 事件处理程序将事件传播到下一个节点,直到根节点。如果你不想那样,那就不要这样做。预期的行为是什么?

标签: angular recursion angular2-template


【解决方案1】:

在您的情况下,每个节点都将自己发送到其父节点,因此应用程序组件始终获取树的根节点。解决方案是在点击事件的情况下将该节点本身发送到父节点,否则只需传递从子节点的事件发射器接收到的内容。

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);
}

【讨论】:

  • 谢谢!这正是我想要的。
猜你喜欢
  • 1970-01-01
  • 2018-03-04
  • 2017-03-18
  • 2023-04-02
  • 1970-01-01
  • 2017-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多