Reputation: 1300
I created a simple stateful pipe based on the Angular.io tutorial on pipes:
@Pipe({
name: 'fetch',
pure: false
})
class FetchJsonPipe implements PipeTransform{
private fetchedValue = 'waiting';
private fetchedValue2 = 'waiting2';
transform(value:string, args:string[]):any {
setTimeout(() => {
this.fetchedValue = 'done';
this.fetchedValue2 = 'done2';
}, 3000);
return this.fetchedValue2;
}
}
@Component({ selector: 'sd-splash'
, template: 'hello ng2 {{ "5" | fetch }}'
, pipes: [FetchJsonPipe]
})
My question is, I return this.fetchedValue
from #transform
immediately.
Since it's just a string, it's returned by value. Later, when the timeout is
finished, I just assign the value 'done'
to a property (which is also
private).
How does Angular2 know that the intial result, 'waiting'
is not final? How
does it know that the updated value will be available through #fetchedValue
?
The promise is not exposed at all, and Angular2 has no information on the name
of the field I store the result in.
The only clue it has is pure == false
, which I guess instructs it to
watch the instance for changes. But I don't see how it has information on
which field to watch.
But it works! And I have no idea why.
Cheers
Upvotes: 4
Views: 1989
Reputation: 52847
Angular monkey patches browser events (including setTimeout()
) using a library called Zone.js. When events happen, AngularJS triggers change detection.
With stateful pipes, AngularJS will re-evaluate the pipe on every event because the pipe result may change even with the same inputs.
With pure pipes, AngularJS will trigger change detection and re-evaluate the pipe only when one of the input changes (i.e. data coming in, or the args).
Upvotes: 6
Reputation: 877
To understand this, I think it's probably best to look at the talk on Zone.js. Basically angular uses a library called zone to do a $rootScope digest after a setTimeout call completes (if it needs to)
Not only that, even after any promise resolution, a digest cycle is triggered.
This is precisely because it doesn't know which properties might have changed, so it dirty checks the entire app.
Upvotes: 2