所以我读了关于Angular 2变化检测的this article,但是看了之后我感到很困惑,所以我开始阅读一些导致更多混淆的评论。
如果组件仅依赖于其输入属性,则它们是 不可变的,那么这个组件可以改变,当且仅当它的一个 输入属性更改。因此,我们可以跳过更改检测树中的组件子树,直到发生此类事件。当它发生时,我们可以检查子树一次,然后禁用它直到下一次更改(灰色框表示禁用更改检测器)。
如果 {{todo.text}} 或 todo.checked 更改,我们标记我们的 todo:Todo 发生了变化
但是根据我的理解,我们可以创建一系列不可变对象。
如果我们积极使用不可变对象,那么很大一部分 更改检测树将在大多数时间禁用。
@Component({changeDetection:ChangeDetectionStrategy.OnPush})
class ImmutableTodoCmp {
todo:Todo;
}
因此,在这种情况下, {{todo.text}} 或 todo.checked 上的任何更改都不会被注意到吗?只有当Todo被推动时我们才会看到变化?
如果组件仅依赖于其输入属性,并且它们是可观察的,那么当且仅当其中一个输入属性发出事件时,此组件才能更改。因此,我们可以跳过更改检测树中的组件子树,直到发生此类事件。当它发生时,我们可以检查一次子树,然后禁用它直到下一次更改。
虽然听起来可能类似于Immutable Objects案例,但它却完全不同。如果您有一个具有不可变绑定的组件树,则更改必须从根开始遍历所有组件。处理可观察事件时情况并非如此。
我不知道Observables与Immutables有什么不同,在Todo应用程序的特定情况下,哪种方法更好?
答案 0 :(得分:17)
所以,就像我们从现在开始的5岁儿童一样。
这是JohnCmp
。 John是一个接受两个输入的组件,name: {first: 'John', last: 'Smith'}
和age: 20
。
如果name
可变,会发生什么?好吧,有人可以将它传递给John
并保留对它的引用。因此,John和 ANY 数量的其他对象或服务可以保存对该name
对象的引用。这意味着他们可以改变它,比如做name.last = 'foo'
。现在约翰的名称更改,但他没有收到新名称。他仍然引用了name
对象,但它发生了变异。
如果我们想检测,我们必须积极检查名称, name.first ,< strong> name.last ,依此类推我们传递的每个对象的每个属性。做name === newName
并且比较参考文献会更容易,嘿? 如果名称是不可变的,我们不需要发疯并检查每个属性,我们可以查看引用并知道对象是否快速更改。
好的,现在,想象一下,没有人持有John
名称对象的引用。因此,如果他们想要给他一个新名称,他们必须传递新名称对象。然后John
在输入更改时仅更改 。这就是这里的意思:
如果组件仅依赖于其输入属性,并且它们是不可变的,那么当且仅当其中一个输入属性发生更改时,此组件才会更改。因此,我们可以跳过更改检测树中的组件子树,直到发生此类事件。
好吧,这是基本案例吗?现在我们不必担心检查每个房产,我们只检查引用尚未更改。大有改善!但对象可能很大。所以people
数组是Array
John
的{{1}},它们是不可变的,name
s也是不可变的。所以为了改变约翰的名字。您需要生成新名称,以及新 John和新人员阵列。
所以他们都改变了,需要遍历整棵树。这就是O(n)
。因此这个小评论:
如果你有一个具有不可变绑定的组件树,则必须从根开始更改所有组件。
BUT
处理可观察物时不是这种情况。
为什么?
Observables发出事件。他们不需要改变像immutables这样的东西,他们只需要emit
改变事件。所以在他的例子中,你没有一个不可变的数组&#34;您需要重新创建并重新评估树中的所有更改。现在你有一个people
observable,它会在事件发生变化时触发它。 John
也会收到一个可观察的内容。
所以你可以在John
中触发一个事件,告诉他他的名字发生了变化,没有触发people
中的事件或类似事件。根据此引用,避免重新扫描所有内容以进行更改,从而将复杂性降低到O(log n)
:
正如您所看到的,这里Todos组件只引用了一个todos数组的可观察对象。 因此无法看到个别待办事项的变化。
(强调我的)。
希望这有帮助。
答案 1 :(得分:8)
我不知道Observable与Immutables有什么不同,在Todo应用程序的特定情况下,哪种方法更好?
想象一下,你有一个节点树,每个节点都有一个位&#34;我可能已经改变了#34; 。对于Observable
,我们谈论的是events getting emitted;事件将向上发送。换句话说:
Todo_ChangeDetector
会被标记,Todos_ChangeDetector
将被标记,App_ChangeDetector
将被标记,想象一下,你有2个待办事项列表:
您当前正在展示的哪个购物清单是Observable
;例如下拉列表,导航丸等。这2个列表下的所有待办事项都可以是Immutable
;例如你不是会议组织者,也不能改变会议。