come funziona il binding e la digestione in AngularJS?

Una cosa che distingue AngularJS da altri framework JavaScript-MVC è la capacità di echo i valori associati da JavaScript in HTML usando i bind. Angular lo fa “automaticamente” quando assegni qualsiasi valore alla variabile $ scope.

Ma quanto è automatico questo? A volte, Angular non rileverà la modifica, quindi ho bisogno di chiamare $ scope. $ Apply () o $ scope. $ Digest () per informare l’angular di ritirare la modifica. A volte, quando eseguo uno di questi metodi, genera un errore e dice che un digest è già in corso.

Poiché i binding (qualsiasi cosa all’interno di {{}} parentesi graffe o ng-attributi) sono echeggiati con eval, ciò significa che Angular sta costantemente interrogando l’object $ scope per cercare le modifiche e quindi eseguire un’eval per spingere quelle modifiche al DOM / HTML? O forse AngularJS ha in qualche modo capito le variabili magiche di utilizzo che generano eventi che vengono triggersti ​​quando un valore variabile cambia o viene assegnato? Non ho mai sentito di essere pienamente supportato da tutti i browser, quindi ne dubito.

In che modo AngularJS tiene traccia delle sue associazioni e variabili di scope?

Oltre alla sezione di documentazione trovata da Mark, penso che possiamo provare ad elencare tutte le possibili fonti di cambiamento.

  1. Interazione dell’utente con input HTML ( ‘testo’ , ‘numero’ , ‘url’ , ’email’ , ‘radio’ , ‘checkbox’ ). AngularJS ha inputDirective . Gli input “text”, “number”, “url” e “email” associano il gestore listener per gli eventi “input” o “keydown”. Il gestore di listener chiama l’ambito. $ Apply . ‘radio’ e ‘checkbox’ associano un gestore simile per l’evento click.
  2. Interazione dell’utente con elemento selezionato. AngularJS ha selezionato Direct con comportamento simile sull’evento ‘change’.
  3. Modifiche periodiche utilizzando il servizio $ timeout che esegue anche $ rootScope. $ Apply () .
  4. EventDirectives (ngClick, ecc.) usa anche scope. $ apply .
  5. $ http usa anche $ rootScope. $ apply () .
  6. Le modifiche al di fuori del mondo di AngularJS dovrebbero utilizzare l’ambito. $ Applicare come sai.

Come hai scoperto, non sta eseguendo il polling, ma utilizzando il ciclo di esecuzione interno, ecco perché è necessario utilizzare $ apply () o $ digest () per dare il via alle cose.

La spiegazione di Miško è abbastanza approfondita, ma il bit mancante è che Angular sta solo cercando di rendere $ scope tornare a uno stato interno chiaro ogni volta che qualcosa accade nel suo contesto. Questo potrebbe richiedere un po ‘di rimbalzi tra gli stati del modello, quindi è anche per questo che non puoi fare affidamento su $ watch () solo una volta e anche perché dovresti stare attento a impostare manualmente le relazioni tra i modelli o finirai all’infinito rinfreschi circolari.