不清楚为什么 parent 在 Angular 初始化之前订阅了 child 的发射器

Unclear why parent subscribed to child's emitter before initialization in Angular

我注意到我必须在声明字段时已经实例化发射器,以避免像 Cannot read 属性 'subscribe' of undefined[=23= 这样的错误].所以下面是我现在的做法,似乎效果很好。

export class ShazooComponent implements OnInit {
  constructor() { }
  @Input() hazaa = new Hazaa();
  @Output() hazaaChange = new EventEmitter<Hazaa>();
  ngOnInit() { }
}

如果我在构造函数中实例化发射器,它也会起作用,这对我来说看起来更好一些。但是,由于与组件相关的订阅和其他组件相关工作在初始化后首先相关,我希望我可以像这样在 ngOnInit() 中执行这些操作。

export class ShazooComponent implements OnInit {
  constructor() { }
  @Input() hazaa = new Hazaa();
  @Output() hazaaChange: EventEmitter<Hazaa>;
  ngOnInit() { this.hazaaChange = new EventEmitter<Hazaa>(); }
}

Apparently,它会导致抛出异常。我一直在阅读有关组件生命周期和那里的挂钩的文档。也许,我还不够聪明,无法抓住它。我需要帮助来理解为什么它不起作用以及它在文档中的位置。我知道 parent 组件在 child 组件初始化之前订阅了发射器,但这对我来说毫无意义。为什么我们要订阅我们知道还没有初始化(并且还不能发出 jack)的东西?

Why would we subscribe to something that we do know isn't inited (and can't emit jack, yet)?

您正在使用 two-way-binding hazaahazaaChange,即 [(hazaa)]="myHazaa"。因此,当创建 parent 时,它会创建您的 child 组件并立即看到您有 two-way-binding,这意味着它会尝试订阅它。那时 parent 只看到:hazaaChange: EventEmitter<Hazaa>,这意味着 hazaaChange 被正确地误认为 undefined。如果你要破坏 two-way-binding,你不会得到错误,但是 two-way-binding 为你做的是为你调用 emit(),在这种情况下,它发生在 parent 已创建,但在 hazaaChange 有时间在 child 中初始化 OnInit

作为旁注,至少在 angular 8 中会抛出一个对用户更友好的错误,而不是您收到的错误。相反,它会出错...

@Output hazaaChange not initialized in 'ShazooChildComponent'.

我认为您应该在创建组件时保留初始化,这样您就确定知道您的事件发射器不是undefined