我无法弄清楚为什么一个事件需要从孩子到父母(@Output
)分享,而@Input()
适用于父母对孩子。
如果我们想要与父组件共享数据而不点击像@Input
那样的任何按钮怎么办?如果组件没有任何关联怎么办?
为什么我们需要一个活动?
因为这会阻止循环引用。如果父母有一个对孩子的引用而且孩子有一个对父母的引用,那么它将是一个循环引用。它还会增加代码的复杂性。如果我正在编写一个“按钮”组件,我不想担心我的按钮组件是什么类型的组件。
如果我们想要与父组件共享数据而不点击@Input的任何按钮,该怎么办?
您可以以编程方式触发事件。例如,您可以使用一个使用RxJS interval
observable的计时器组件每5秒触发一次事件。
interval(5000).subscribe(() => myOutput.next());
如果组件没有任何关联怎么办?
然后他们应该通过共享服务进行通信,而不是使用Input
和Output
。
对于你问题的第一部分,我想详细说明:
我无法弄清楚为什么你需要一个事件来发生从子到父(@Output)共享数据,而@Input()适用于父对子。
因为Angular有一个单向变化检测系统,从上到下。
这意味着父级中的更改将传播到子级,而不是相反,通过设计,使应用程序状态的流更容易理解。
对于绑定属性(例如用@input
修饰的属性),父级中值(对于基元)或引用(对象)的更改将导致更改检测触发,并且将使用新值或引用更新子项。
但是,例如,在子项中重新分配@input
属性将不会更新父项中的引用,因为这将违反上述自上而下的设计。
虽然有一个输出装饰器,但是从下到上没有变化检测,因此必须明确告知父方向的这方面的变化,例如:与事件,这正是发生的事情。
进一步说明
尽管如此,对孩子中的绑定属性的更改仍然可能导致在父级中看到更改。当对象引用传递给子进程并且子进程使用引用变异对象时会发生这种情况,因为最终它仍然是Javascript,父对象和子进程都引用了同一个对象。如果其他东西导致更改检测在父级中触发,则更新DOM并在屏幕上观察到此突变的影响。
但是,这段代码很难理解和调试,而@output
是声明性的和清晰的。