为什么来自 mat-dialog 回调的事件已发送但未收到?

Why are events from mat-dialog callback sent but not received?

我有一个自定义结构指令,在其中显示 MatDialog.
在对话框的 afterClosed() 中发出了一个事件。

问题是事件 已发送但未收到 (在下面的示例中未调用 onHappened())。
如果我用 of(true) 替换 ... afterClosed(),一切正常。

为什么会出现这个问题? 我该如何解决?

Stackblitz example。下面是一些代码片段。

menu-icons-example.html

中的指令用法
...
<mat-menu #menu="matMenu">
  <ng-template matMenuContent>
    <ng-template appExample (happened)="onHappened()">
      <button mat-menu-item>
        <mat-icon>pause</mat-icon>
        <span>Pause</span>
      </button>
    </ng-template>
  </ng-template>
</mat-menu>
...

example.directive.ts

@Directive({
  selector: '[appExample]'
})
export class ExampleDirective implements OnInit {
  @Output() readonly happened = new EventEmitter<void>();
  private condition = true;

  constructor(
    private readonly dialog: MatDialog,
    private readonly templateRef: TemplateRef<any>,
    private readonly viewContainer: ViewContainerRef,
    private readonly renderer: Renderer2
  ) {
  }

  ngOnInit(): void {
    if (this.condition) {
      const ref = this.viewContainer.createEmbeddedView(this.templateRef);

      this.renderer.listen(ref.rootNodes[0], 'click', () => this.onClick());
    }
  }

  onClick(): void {
    this.dialog.open(DialogComponent).afterClosed()
    // of(void 0) works well
    .subscribe(() => {
      this.happened.emit();
      console.log('emitted');
    });
  }

您 运行 遇到了一个有趣的情况,即菜单在对话框打开后立即关闭,因此指令被销毁。一旦它被销毁,事件发射器也随之被销毁,并且不能发出任何事件。 (编辑:准确地说,事件发射器并没有被销毁,但是由于指令被销毁了,所以它与外界的输出连接被移除了。)

检查你的 forked StackBlitz,我在指令的 ngOnDestroy 中添加了一个日志,你可以看到它在对话框打开时被调用。