观察到不可变的变化检测 [英] Change detection with Observable vs Immutable

查看:99
本文介绍了观察到不可变的变化检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我阅读了有关Angular 2更改的这篇文章检测,但阅读后我变得更加困惑,因此我开始阅读一些引起更多困惑的评论.

So I read this article about Angular 2 change detection, but after reading it I have got more confused, so I started reading some of the comments which led to more confusion.

如果组件仅取决于其输入属性,并且它们是 不可变的,那么当且仅当其组件之一 输入属性更改.因此,我们可以在变更检测树中跳过组件的子树,直到发生此类事件为止.发生这种情况时,我们可以检查一次子树,然后将其禁用,直到下一次更改为止(灰色框表示禁用的更改检测器).

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 >发生了变化

So if {{todo.text}} or todo.checked change we mark our todo:Todo that a changed has occurred

但是据我了解,我们可以创建一堆不可变的对象.

But then from my understanding, we can create a cascade of immutable objects.

如果我们积极使用不可变对象,那么其中很大一部分 更改检测树大部分时间都将被禁用.

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 上的任何更改吗?只有当按下待办事项时,我们才会看到变化吗?

So in this case, any changes on {{todo.text}} or todo.checked won't be noticed right? only when a Todo is pushed we will see a change?

如果组件仅取决于其输入属性,并且可以观察到,则只有当其输入属性之一发出事件时,此组件才能更改.因此,我们可以在变更检测树中跳过组件的子树,直到发生此类事件为止.发生这种情况时,我们可以检查一次子树,然后禁用它直到下一次更改.

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?

推荐答案

所以,就像我们从现在起5岁.

So, like we are 5 year olds from now on.

这是JohnCmp. John是一个接受两个输入,一个name: {first: 'John', last: 'Smith'}age: 20的组件.

This is JohnCmp. John is a component that accepts two inputs, a name: {first: 'John', last: 'Smith'} and an age: 20.

如果name可变,会发生什么?好吧,有人可以将其传递给John并保留对其的引用.这样,John和 ANY 个其他对象或服务就可以保存对该name对象的引用.这意味着他们可以更改它,例如执行name.last = 'foo'. John的名称现在更改,但是他没有收到名称.他仍然引用了该name对象,但是该对象发生了变化.

What happens if name is mutable? Well, someone could pass it to John and hold a reference to it. So that John, and ANY number of other objects or services can hold a reference to that name object. This means they can change it, say doing name.last = 'foo'. And John's name changes now, but he didn't receive a new name. He still has a reference to that name object, but it mutated.

如果要检测,我们必须积极检查名称名称.first name.last ,以此类推,以及我们传递的每个对象的每个属性. name === newName进行比较并比较引用会容易得多吗? 如果名称是不变的,我们就不必发疯并检查每个属性,我们可以检查引用并知道对象是否快速更改.

If we want to detect this, we have to aggressively check name, name.first, name.last, and so on with every property of every object we pass around. How much easier would it be to do name === newName and just compare references, hey? If name is immutable, we don't need to go crazy and check every property, we can check references and know if an object is changed quickly.

好吧,现在,想象没有人拥有对John name 对象的引用.因此,如果他们想给他起一个新名字,则必须传递一个 NEW 名字对象.然后,当John输入发生更改时,仅更改.这是这里的意思:

Ok, now, imagine nobody holds a reference to John's name object. So if they want to give him a new name, they must pass in a NEW name object. Then John changes only when his input changes. This is what is meant here:

如果组件仅取决于其输入属性,并且它们是不可变的,则当且仅当其输入属性之一发生更改时,此组件才可以更改.因此,我们可以在变更检测树中跳过组件的子树,直到发生此类事件为止.

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数组是不可变的John的不可变Array,也是不可变的name的不可变.所以为了改变约翰的名字.您需要产生一个 new 名称,一个 new John和一个 new 人员数组.

Alright, so that's the basic case right? Now we don't have to worry about checking every property, we just check that references haven't changed. Much improved! BUT objects can be large. So a people array is an immutable Array of Johns, which are immutable, of names that are also immutable. So in order to change John's name. you need to produce a new name, and a new John, and a new people array.

因此它们都发生了变化,需要遍历整个树.这就是O(n).因此,这个小评论:

So they all change, the whole tree needs to be traversed. So that's O(n). Hence this little comment:

如果您的组件树具有不可更改的绑定,则必须从根开始对所有组件进行更改.

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.

为什么?

可观察对象发出事件.他们不需要更改任何东西,如不可变对象,只需要emit更改事件.因此,在他的示例中,您不需要重新创建不变的数组",因此无需重新评估树上的所有更改.现在,您有了一个people可观察对象,它在更改时会触发事件.而且John也会收到一个可观察到的信号.

Observables emit events. They don't need to change everything like immutables, they just need to emit a change event. So in his example, you don't have an immutable "array" that you need to recreate and therefore re-evaluate all the changes up the tree. Now you have a people observable, that triggers events when it changes. And John receives an observable as well.

因此,您只需在John中触发一个事件,告诉他他的名字已更改,而无需在people中触发一个事件或类似的事件.避免按照此引文重新扫描所有内容以进行更改,从而将复杂度降低到O(log n):

So you can just trigger an event in John telling him that his name changed, WITHOUT triggering an event in people or things of the sort. Avoiding you to re scan everything for changes, thus reducing complexity to O(log n), as per this quote:

如您所见,这里的Todos组件仅对可观察到的todos数组的引用. 因此它看不到各个待办事项中的更改.

(重点是我的).

希望这会有所帮助.

这篇关于观察到不可变的变化检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆