使用 Observable 与 Immutable 进行变化检测
Change detection with Observable vs Immutable
所以我阅读了 this article 关于 Angular 2 变化检测的内容,但在阅读之后我变得更加困惑,所以我开始阅读一些导致更多困惑的评论。
不可变对象
If a component depends only on its input properties, and they are
immutable, then this component can change if and only if one of its
input properties changes. Therefore, we can skip the component’s subtree in the change detection tree until such an event occurs. When it happens, we can check the subtree once, and then disable it until the next change (gray boxes indicate disabled change detectors).
所以如果 {{todo.text}} 或 todo.checked 改变我们 mark 我们的 todo:Todo 发生了变化
但根据我的理解,我们可以创建一系列不可变对象。
If we are aggressive about using immutable objects, a big chunk of the
change detection tree will be disabled most of the time.
@Component({changeDetection:ChangeDetectionStrategy.OnPush})
class ImmutableTodoCmp {
todo:Todo;
}
所以在这种情况下,{{todo.text}} 或 todo.checked 的任何更改都不会'不会被注意到吧?只有当 Todo 被推送时我们才会看到变化?
可观察对象
If a component depends only on its input properties, and they are observable, then this component can change if and only if one of its input properties emits an event. Therefore, we can skip the component’s subtree in the change detection tree until such an event occurs. When it happens, we can check the subtree once, and then disable it until the next change.
Although it may sound similar to the Immutable Objects case, it is quite different. If you have a tree of components with immutable bindings, a change has to go through all the components starting from the root. This is not the case when dealing with observables.
我不明白 Observables 与 Immutables 有何不同,在 Todo 应用程序的这种特定情况下,哪种方法更好?
I don't get it how Observables are quite different from Immutables and in this specific case of the Todo app, which approach is better?
假设您有一棵节点树,每个节点都有一个位表示 "I may have changed"。 Observable
,就是events getting emitted;事件在树 上调度 。换句话说:
Todo_ChangeDetector
会被标记,
- 然后往树上走,
Todos_ChangeDetector
会被标记,
- 然后往树上走,
App_ChangeDetector
会被标记,
- 然后 正常变化检测开始。
假设您有 2 个待办事项列表:
- 购物清单。
- 当天的会议(工作?)列表。
您当前显示的哪个购物清单是活动的Observable
;例如下拉菜单、导航丸等。这两个列表下的所有待办事项都可以是 Immutable
;例如您不是会议组织者,无法更改会议。
所以,从现在开始就像我们5岁一样。
这是JohnCmp
。 John 是一个接受 两个 输入的组件,一个 name: {first: 'John', last: 'Smith'}
和一个 age: 20
.
如果 name
可变会怎样?好吧,有人可以将它传递给 John
并保留对它的引用。这样 John 和 ANY 数量的其他对象或服务可以持有对该 name
对象的引用。这意味着他们可以更改它,比如 name.last = 'foo'
。 John 的名字现在更改,但他没有收到新 名字。他仍然引用那个 name
对象,但它发生了变化。
如果我们想要检测这个,我们必须积极地检查名称,name.first、name.last,以此类推我们每个对象的每个属性绕过。做 name === newName
并比较参考资料会容易得多,嘿? 如果 name 是不可变的,我们就不需要疯狂地检查每个 属性,我们可以检查引用并知道一个对象是否被快速更改。
好的,现在,假设没有人持有对 John
的 name 对象的引用。所以如果他们想给他起一个新名字,他们必须传入一个NEW名字对象。然后 John
在他的 input 改变时改变 only。这就是这里的意思:
If a component depends only on its input properties, and they are immutable, then this component can change if and only if one of its input properties changes. Therefore, we can skip the component’s subtree in the change detection tree until such an event occurs.
好的,这就是基本情况,对吗?现在 我们不必担心检查每个 属性,我们只需检查 引用没有改变。大大改善!但是对象可以很大。因此,people
数组是不可变的 Array
of John
s,它们是不可变的,name
s 也是不可变的。所以为了改变约翰的名字。你需要生成一个 new 名字,一个 new John,和一个 new people 数组。
所以都变了,需要遍历整棵树。那就是 O(n)
。因此这个小评论:
If you have a tree of components with immutable bindings, a change has to go through all the components starting from the root.
但是
This is not the case when dealing with observables.
为什么?
Observable 发出事件。他们不需要像不可变的那样改变一切,他们只需要 emit
一个改变事件。因此,在他的示例中,您没有需要重新创建的不可变 "array",因此 re-evaluate 树上的所有更改。现在你有一个 people
observable,当它改变时触发事件。 John
也接收到一个可观察对象。
所以你可以在 John
中触发一个事件,告诉他他的名字改变了,而无需在 people
中触发一个事件或类似的事情。避免您重新扫描所有内容以进行更改,从而将复杂性降低到 O(log n)
,根据此引用:
As you can see, here the Todos component has only a reference to an observable of an array of todos. So it cannot see the changes in individual todos.
(强调我的)。
希望这对您有所帮助。
所以我阅读了 this article 关于 Angular 2 变化检测的内容,但在阅读之后我变得更加困惑,所以我开始阅读一些导致更多困惑的评论。
不可变对象
If a component depends only on its input properties, and they are immutable, then this component can change if and only if one of its input properties changes. Therefore, we can skip the component’s subtree in the change detection tree until such an event occurs. When it happens, we can check the subtree once, and then disable it until the next change (gray boxes indicate disabled change detectors).
所以如果 {{todo.text}} 或 todo.checked 改变我们 mark 我们的 todo:Todo 发生了变化
但根据我的理解,我们可以创建一系列不可变对象。
If we are aggressive about using immutable objects, a big chunk of the change detection tree will be disabled most of the time.
@Component({changeDetection:ChangeDetectionStrategy.OnPush})
class ImmutableTodoCmp {
todo:Todo;
}
所以在这种情况下,{{todo.text}} 或 todo.checked 的任何更改都不会'不会被注意到吧?只有当 Todo 被推送时我们才会看到变化?
可观察对象
If a component depends only on its input properties, and they are observable, then this component can change if and only if one of its input properties emits an event. Therefore, we can skip the component’s subtree in the change detection tree until such an event occurs. When it happens, we can check the subtree once, and then disable it until the next change.
Although it may sound similar to the Immutable Objects case, it is quite different. If you have a tree of components with immutable bindings, a change has to go through all the components starting from the root. This is not the case when dealing with observables.
我不明白 Observables 与 Immutables 有何不同,在 Todo 应用程序的这种特定情况下,哪种方法更好?
I don't get it how Observables are quite different from Immutables and in this specific case of the Todo app, which approach is better?
假设您有一棵节点树,每个节点都有一个位表示 "I may have changed"。 Observable
,就是events getting emitted;事件在树 上调度 。换句话说:
Todo_ChangeDetector
会被标记,- 然后往树上走,
Todos_ChangeDetector
会被标记, - 然后往树上走,
App_ChangeDetector
会被标记, - 然后 正常变化检测开始。
假设您有 2 个待办事项列表:
- 购物清单。
- 当天的会议(工作?)列表。
您当前显示的哪个购物清单是活动的Observable
;例如下拉菜单、导航丸等。这两个列表下的所有待办事项都可以是 Immutable
;例如您不是会议组织者,无法更改会议。
所以,从现在开始就像我们5岁一样。
这是JohnCmp
。 John 是一个接受 两个 输入的组件,一个 name: {first: 'John', last: 'Smith'}
和一个 age: 20
.
如果 name
可变会怎样?好吧,有人可以将它传递给 John
并保留对它的引用。这样 John 和 ANY 数量的其他对象或服务可以持有对该 name
对象的引用。这意味着他们可以更改它,比如 name.last = 'foo'
。 John 的名字现在更改,但他没有收到新 名字。他仍然引用那个 name
对象,但它发生了变化。
如果我们想要检测这个,我们必须积极地检查名称,name.first、name.last,以此类推我们每个对象的每个属性绕过。做 name === newName
并比较参考资料会容易得多,嘿? 如果 name 是不可变的,我们就不需要疯狂地检查每个 属性,我们可以检查引用并知道一个对象是否被快速更改。
好的,现在,假设没有人持有对 John
的 name 对象的引用。所以如果他们想给他起一个新名字,他们必须传入一个NEW名字对象。然后 John
在他的 input 改变时改变 only。这就是这里的意思:
If a component depends only on its input properties, and they are immutable, then this component can change if and only if one of its input properties changes. Therefore, we can skip the component’s subtree in the change detection tree until such an event occurs.
好的,这就是基本情况,对吗?现在 我们不必担心检查每个 属性,我们只需检查 引用没有改变。大大改善!但是对象可以很大。因此,people
数组是不可变的 Array
of John
s,它们是不可变的,name
s 也是不可变的。所以为了改变约翰的名字。你需要生成一个 new 名字,一个 new John,和一个 new people 数组。
所以都变了,需要遍历整棵树。那就是 O(n)
。因此这个小评论:
If you have a tree of components with immutable bindings, a change has to go through all the components starting from the root.
但是
This is not the case when dealing with observables.
为什么?
Observable 发出事件。他们不需要像不可变的那样改变一切,他们只需要 emit
一个改变事件。因此,在他的示例中,您没有需要重新创建的不可变 "array",因此 re-evaluate 树上的所有更改。现在你有一个 people
observable,当它改变时触发事件。 John
也接收到一个可观察对象。
所以你可以在 John
中触发一个事件,告诉他他的名字改变了,而无需在 people
中触发一个事件或类似的事情。避免您重新扫描所有内容以进行更改,从而将复杂性降低到 O(log n)
,根据此引用:
As you can see, here the Todos component has only a reference to an observable of an array of todos. So it cannot see the changes in individual todos.
(强调我的)。
希望这对您有所帮助。