Angular: EventEmitter 的事件未通过 .subscribe 成功接收

Angular: EventEmitter's event wasn't successfully received via .subscribe

我正在尝试通过引用传递 EventEmitter 对象并调用 .subscribe(),在 NgDNDirective 的方法 EV 中处理来自 NgLoopDirective 的事件在下面的代码中:

import { Directive, Input, ElementRef, Renderer2, EventEmitter } from '@angular/core';

@Directive({
  selector: '[ngDN]'
})
export class NgDNDirective {

  private dn: number = -1
  private ev: EventEmitter<void>;

  @Input() set ngDN(dn: number) {
    this.dn = dn
  }

  @Input() set EV(ref: {ev: EventEmitter<void>}) {
    console.log('waiting for ev')
    ref.ev.subscribe(() => {
      console.log('data-num:', this.dn)
      this.renderer.setAttribute(this.elRef, 'data-num', this.dn.toString())
    })
  }

  constructor(private elRef: ElementRef,
              private renderer: Renderer2) {}

}

@Directive({
  selector: '[ngLoop]'
})
export class NgLoopDirective {

  @Input() set ngLoop(iter_count: number) {
    this.container.clear()
    for (let i=0; i<iter_count; i++) {
      let ev: EventEmitter<void> = new EventEmitter<void>()
      let ref = {ev: ev}

      this.container.createEmbeddedView(this.template, {index: i, ev: ref})
      ev.emit()
    }
  }

  constructor(private template: TemplateRef<any>,
              private container: ViewContainerRef) {}

}

这是使用过的HTML代码:

<ng-template [ngLoop]="10" let-i="index" let-ref="ev">
  <a href="#" [ngDN]="i" [EV]="ref"></a>
</ng-template>

当我在控制台下调试代码时 - 我只看到这条消息:

waiting for ev

表示事件未成功处理,因为未调用 console.log('data-num:', this.dn)

应该是什么导致了这个问题?

Angular 运行 发出事件后 NgDNDirective 的更改检测。

因此 运行 手动更改检测:

const view = this.container.createEmbeddedView(this.template, {index: i, ev: ref});
view.detectChanges();

Plunker Example

或使用ReplaySubject代替EventEmitter

Plunker Example