我想知道是否可以通过在区域中包装所有组件逻辑(包括组件内非组件指令的逻辑)将所有异步事件和回调追溯到特定的源组件,然后只需要检查该源组件假设所有更改都遵循单向流,则更改以及来自源组件的更改输入的任何子组件的更改。
这种理解是否合理?
Angular2中是否提供此更改检测策略?
为什么Angular2会在任何异步(XHR)事件后检测所有组件的更改?
答案 0 :(得分:1)
一个完整的Angular应用程序在单个区域中运行。 Angular使用区域来修补异步API,并使用来自这些修补API的通知在每次发生某些异步事件时运行更改检测。
单向流用于[prop]="value"
绑定,仅适用于父节点到子节点。
Angular运行更改从根到叶子的检测。
如果为组件配置了ChangeDetectionStrategy.OnPush
,则更改检测会跳过这些组件(及其后代),直到某些绑定(输入)发生更改。
还有其他优化CD的策略。
例如可观察和承诺,主动通知变更并且不需要变更检测。
保证不会改变其属性值的不可变对象。
<强>更新强>
Angular不知道事件处理程序已更改的值。传递的对象引用的组件,全局服务的属性,......它只是假设在调用事件处理程序时可能已经发生了某些变化,然后运行完整的更改检测周期来传播来自的所有绑定父母对孩子。
子进行父进程绑定无论如何都是事件,因此在更改检测期间不会更新。
答案 1 :(得分:1)
...通过将所有组件逻辑(包括组件内部的非组件指令的逻辑)包装在一个区域中,然后只需要检查该源组件的变化以及来自源组件的更改输入的任何子组件,假设所有变化都遵循单向流动。这种理解是否合理?
当模板绑定事件触发时 - 例如(click)="doSomething()"
- doSomething()
方法可以随意更改任何组件或应用程序数据。模板语句,例如我们的doSomething()
事件处理程序,不受单向流规则的约束,根据Angular docs:
响应事件是Angular&#34;单向数据流的另一面&#34;。在此次事件循环中,我们可以随时随地更改任何内容。
这就是为什么默认情况下,Angular的更改检测必须在事件触发后检查每个组件中的每个模板绑定。 (好吧,在Angular区域内的一个事件发生之后。)Angular并不知道可能会发生什么变化......它必须发现已经发生了什么变化。
unidirectional flow rule适用于模板表达式,例如{{some expression}}
或[childInputProperty]="parent expression"
,或者如果您实现了输入属性setter方法:@Input() set childInputProperty(variableName:type) { ... }
。< / p>
Angular2中是否提供此更改检测策略?
不,因为它会严重限制事件处理程序可以执行的操作。对每个模板绑定进行脏检查可能不是检测更改的最有效方法,但它使我们更容易编写事件处理程序(即编写应用程序)。
为什么Angular2会在任何异步(XHR)事件后检测所有组件的更改?
Angular并不想限制我们在事件处理程序中可以执行的操作。 ComponentA模板中绑定的事件处理程序可以更改ComponentA本地的数据,但它也可以更改服务中的数据(因此它可以更改其他组件可见的数据),并且可以更改其他组件中的数据,例如,通过调用其他组件上的公共API /方法。