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
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).
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