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).
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;
}
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.
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?
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.
Undoubtedly, you should stick to immutable data structures in Angular applications. Not only does it allow you to improve a runtime performance by using the OnPush change detection strategy, but it also prevents you from getting into troubles of having stale data rendered in the view.
You can declare Observable<boolean> or whatever you will still have NaN .
Observable in Angular is a feature that provides support for delivering messages between different parts of your single-page application. This feature is frequently used in Angular because it is responsible for handling multiple values, asynchronous programming in Javascript, and also event handling processes.
So, like we are 5 year olds from now on.
This is JohnCmp
. John is a component that accepts two inputs, a name: {first: 'John', last: 'Smith'}
and an age: 20
.
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.
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.
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.
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 John
s, which are immutable, of name
s 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.
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.
BUT
This is not the case when dealing with observables.
Why tho?
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.
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:
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.
(emphasis mine).
Hope this helps.
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?
Imagine that you have a tree of nodes, and each node has a bit that says "I may have changed". With Observable
, we are talking about events getting emitted; the event is dispatched up the tree. In other words:
Todo_ChangeDetector
would be flagged,Todos_ChangeDetector
would be flagged,App_ChangeDetector
would be flagged,Imagine you have 2 todo lists:
Which grocery list is active you are currently showing would be the Observable
; e.g. a dropdown, nav pills, etc. All the todo items under those 2 lists could be Immutable
; e.g. you are not the meeting organizer and cannot change the meetings.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With