angular - Hvordan opdager angular2 ændringer i en stateful pipe?
Jeg lavede et simpelt stateful pipe baseret på Angular.io-vejledningen om 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]
})
Mit spørgsmål er, jeg returnerer this.fetchedValue fra #transform med det samme. Da det bare er en streng, returneres det efter værdi. Senere, når timeout'en er færdig, tildeler jeg bare værdien 'done' til en egenskab (som også er privat).
Hvordan ved Angular2, at det oprindelige resultat, 'waiting', ikke er endeligt? Hvordan ved det, at den opdaterede værdi vil være tilgængelig gennem #fetchedValue? Promisen er slet ikke eksponeret, og Angular2 har ingen information om navnet på det felt, jeg gemmer resultatet i.
Det eneste spor, den har, er pure == false, hvilket jeg gætter instruerer den til at overvåge instansen for ændringer. Men jeg kan ikke se, hvordan den har information om hvilket felt den skal overvåge.
Men det virker! Og jeg har ingen idé om hvorfor.
Skål
Svar #1
Angular monkey-patcher browserhændelser (inklusive setTimeout()) ved hjælp af et bibliotek kaldet Zone.js. Når hændelser sker, udløser AngularJS ændringsdetektion.
Med stateful pipes vil AngularJS genvurdere pipen ved hver begivenhed, fordi pipe-resultatet kan ændre sig selv med de samme input.
Med rene pipes vil AngularJS udløse ændringsdetektion og genberegne pipe'en kun, når en af inputtene ændres (dvs. data der kommer ind, eller argumenterne).
Svar #2
For at forstå dette, tror jeg, det sandsynligvis er bedst at se på foredraget om Zone.js. Grundlæggende bruger Angular et bibliotek kaldet zone til at udføre en $rootScope digest efter, at et setTimeout-opkald er færdigt (hvis det er nødvendigt).
Ikke nok med det, selv efter enhver løfteløsning udløses en digest-cyklus.
Dette er netop fordi det ikke ved, hvilke egenskaber der måtte have ændret sig, så det tjekker hele appen for ændringer.