I tried to read a lot about zones in angular 2. I got to know that angular uses of zone.js
for change detection. I see some code used zone.run
and place few actions inside of it.
What does it do actually? One thing I understood is that it executes these commands as separate block. Still I could not figure out the actual use of zone.run
To learn more about NgZone
read:
What does it do actually?
Zone.run
allows you to change the current zone. Here is the basic example:
console.log(Zone.current.name); // <root>
setTimeout(() => console.log(Zone.current.name)); <root>
// we're in the <root> zone now, but when we call `run` on the instance of zone `A` we change the zone
Zone.current.fork({name: 'A'}).run(() => {
console.log(Zone.current.name); // A
setTimeout(() => console.log(Zone.current.name)); // A
});
// again we're back in the <root> zone now, but when we call `run` on the instance of zone `B` we change the zone
Zone.current.fork({name: 'B'}).run(() => {
console.log(Zone.current.name); // B
setTimeout(() => console.log(Zone.current.name)); // B
});
Zone.current.fork
creates a new zone. It returns the reference to this new zone and by using run
you can execute an asynchronous action inside this zone. You can see above that the setTimeout
async task persists correct zone across the time.
Angular creates its own zone:
function forkInnerZoneWithAngularBehavior(zone: NgZonePrivate) {
zone._inner = zone._inner.fork({
name: 'angular',
properties: <any>{'isAngularZone': true},
...
And this new zone is what you get when you inject NgZone
into class constructors:
constructor (zone: NgZone) {}
You need to use zone.run()
when the current execution zone is not Angular zone (NgZone) - Zone.current.name !== 'angular'
. If it's the case you need all async tasks scheduled from this zone will not be picked up by Angular and it won't schedule change detection. So you can switch to Angular zone for some async tasks:
Zone.current.fork({name: 'A'}).run(() => {
// this timeout won't be picked up by Angular
setTimeout(() => console.log(Zone.current.name)); // A
// this timeout will be picked up by Angular
NgZone.run(() => setTimeout(() => console.log(Zone.current.name)));
});
Sometimes you may also do the opposite and run some async tasks outside of Angular zone. Use runOutsideAngular
method for that:
NgZone.runOutsideAngular(()=>{ ... })
What is Zone.js?
A Zone is an execution context that persists across async tasks. You can think of it as thread-local storage for JavaScript VMs.
How does it work?
zone.js patches most standard web APIs(such as DOM events, XMLHttpRequest...) and nodejs APIs (EventEmitter,fs ...).
How does it apply to Angular?
Angular relies on Zone.js to patch browser events so that it can trigger change detection after the event is complete. This allows you to use POJO (plain old javascript objects).
Note: if you want to see an example of how it patches browser events, try doing an alert(setTimeout)
You may want to use Zone.run
to manually trigger change detection for asynchronous events that Angular is unaware of. For example, you may use Zone.run
for custom defined events triggered from a 3rd party component.
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