EventEmitter和递归

Dar*_*lyn 2 angular

当我有一个带选择器的模板时'recursive-element',它的模板看起来像这样

<li *ngFor="let x of y" (click)="greet($event)">
   <div *ngIf="x.children">
      <recursive-element [y]="x.children"></recursive-element>
    </div>
</li>
Run Code Online (Sandbox Code Playgroud)

在我定义的课程中

greetEvent = new EventEmitter();
greet(e){
  greetEvent.emit("hello world!");
  e.stopPropagation();
}
Run Code Online (Sandbox Code Playgroud)

在另一个组件中,我将它添加到tempalte例如

hi(x){
  alert(x)
}
Run Code Online (Sandbox Code Playgroud)

当我点击嵌套时recurive-element,事件不会触发但是当我点击第一个li元素时它会触发

是因为递归所以甚至只绑定到第一个递归元素而不是嵌套的元素或者是否有一些我不理解的东西?

Ofe*_*man 9

angular2中的自定义事件不会冒泡,因此您可以:

  1. <recursive-element>当其中一个孩子发出事件时发出父事件- 这将为EventEmitter每个孩子创建一个新事件.

在这种情况下,子组件应该是这样的:

@Component({
    selector: 'recursive-comp',
    template: `
        <div>
        <div *ngFor="let item; of tree;">
        <a href="#" (click)="onClick(item)">{{item.name}}</a>
        <recursive-comp *ngIf="item.children" [tree]="item.children" (clickEvent)="onClickChild($event)"></recursive-comp>
        </div>
        </div>
    `
})
export class RecursiveCmp {
    @Input() tree = null;
    @Output() clickEvent = new EventEmitter();

    constructor() {

    }

    onClick(item) {
        console.log("clicked", item);
        this.clickEvent.emit(item);
    }

    onClickChild(item) {
        this.clickEvent.emit(item);
    }
}
Run Code Online (Sandbox Code Playgroud)

看看每个孩子的事件

  1. 创建一个服务,该服务将保留EventEmitter父级和子级,并将由父级和子级使用.为此,服务应该是单一的,因此最好的选择是在bootstrap时间注册提供者.

这是服务代码:

@Injectable()
export class ClickerService {
   clickEvent = new EventEmitter();

   clicked(item) {
     this.clickEvent.emit(item);
   }
}
Run Code Online (Sandbox Code Playgroud)

和子组件:

@Component({
  selector: 'recursive-comp',
  template: `
    <div>
      <div *ngFor="let item; of tree;">
        <a href="#" (click)="onClick(item)">{{item.name}}</a>
        <recursive-comp *ngIf="item.children" [tree]="item.children"></recursive-comp>
      </div>
    </div>
  `
})
export class RecursiveCmp {
  @Input() tree = null;
  constructor(private clickerService: ClickerService) {}

  onClick(item) {
    this.clickerService.clicked(item);
  }
}
Run Code Online (Sandbox Code Playgroud)

看到这个服务活动的plunker