用Observable和Immutable改变检测

时间:2015-12-16 13:44:10

标签: angular

所以我读了关于Angular 2变化检测的this article,但是看了之后我感到很困惑,所以我开始阅读一些导致更多混淆的评论。

不可变对象

  

如果组件仅依赖于其输入属性,则它们是   不可变的,那么这个组件可以改变,当且仅当它的一个   输入属性更改。因此,我们可以跳过更改检测树中的组件子树,直到发生此类事件。当它发生时,我们可以检查子树一次,然后禁用它直到下一次更改(灰色框表示禁用更改检测器)。

如果 {{todo.text}} todo.checked 更改,我们标记我们的 todo:Todo 发生了变化 Immutable objects

但是根据我的理解,我们可以创建一系列不可变对象。

  

如果我们积极使用不可变对象,那么很大一部分   更改检测树将在大多数时间禁用。

cascade immutable obejcts

@Component({changeDetection:ChangeDetectionStrategy.OnPush})
class ImmutableTodoCmp {
  todo:Todo;
}

因此,在这种情况下, {{todo.text}} todo.checked 上的任何更改都不会被注意到吗?只有当Todo被推动时我们才会看到变化?

可观察对象

  

如果组件仅依赖于其输入属性,并且它们是可观察的,那么当且仅当其中一个输入属性发出事件时,此组件才能更改。因此,我们可以跳过更改检测树中的组件子树,直到发生此类事件。当它发生时,我们可以检查一次子树,然后禁用它直到下一次更改。

     

虽然听起来可能类似于Immutable Objects案例,但它却完全不同。如果您有一个具有不可变绑定的组件树,则更改必须从根开始遍历所有组件。处理可观察事件时情况并非如此。

我不知道Observables与Immutables有什么不同,在Todo应用程序的特定情况下,哪种方法更好?

2 个答案:

答案 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个待办事项列表:

  1. 购物清单。
  2. 当天的会议清单(工作?)。
  3. 您当前正在展示的哪个购物清单是Observable;例如下拉列表,导航丸等。这2个列表下的所有待办事项都可以是Immutable;例如你不是会议组织者,也不能改变会议。