2015-05-24 14 views
8

AngularJS consente di implementare il binding dei dati bidirezionale. Tuttavia, la parte interessante è il modo in cui rileva i cambiamenti del modello? Il modello è solitamente un oggetto semplice come il seguente codice. Possiamo cambiare la proprietà del nome di $scope.user ma in che modo AngularJS rileva il modello modificato? AngularJS enum tutte le proprietà dell'oggetto $scope?In che modo AngularJS implementa il suo meccanismo di associazione dati bidirezionale?

angular.module('myApp', []) 
     .controller('BusinessCardController', function($scope){ 
     $scope.user = { 
      name: 'Tanay Pant' 
     } 
     }); 

<input type="text" ng-model="user.name" placeholder="Full Name" /> 

risposta

10

C'è un ciclo di digest, la cui portata esamina tutte le espressioni di controllo $ e li confronta con il valore precedente. Analizza i modelli oggetto per le modifiche, se il vecchio valore non è uguale al nuovo valore, AngularJS aggiornerà le posizioni appropriate, a.k.un controllo sporco.

Per eseguire il ciclo digest da eseguire $apply(fn), è possibile accedere al mondo angolare da JavaScript. Come fa $apply(fn) ottenere chiamato (tratto da AngularJs integration with browser):

  1. attese evento-ciclo del browser per un evento per arrivare. Un evento è un'interazione dell'utente, un evento del timer o un evento di rete (risposta da un server).
  2. Il callback dell'evento viene eseguito. Questo entra nel contesto JavaScript. Il callback può modificare la struttura DOM.
  3. Una volta eseguito il callback, il browser lascia il contesto JavaScript e esegue nuovamente il rendering della vista in base alle modifiche DOM.

Data Binding

Digest Cycle Explanation

Per realizzare due vie vincolante, direttive Registrazione osservatori. Perché una pagina sia veloce ed efficiente dobbiamo cercare di ridurre tutti questi osservatori che creiamo. Quindi dovresti fare attenzione quando usi il binding a due vie, ad esempio usalo solo quando ne hai davvero bisogno. In caso contrario, utilizzare a senso unico:

<h1> {{ ::vm.title }} </h1>

Qui è del tutto evidente che il titolo della pagina, probabilmente non verrà modificato mentre l'utente si trova nella pagina - o ha bisogno di vedere quello nuovo, se è cambiato. Quindi possiamo usare :: per registrare un legame unidirezionale durante la fase di collegamento del modello.

I problemi principali che ho riscontrato con le esplosioni di osservatori sono le griglie con centinaia di righe. Se queste righe hanno un numero piuttosto ridotto di colonne e in ogni cella esiste un collegamento dati bidirezionale, allora sei pronto per un trattamento. Puoi sederti e aspettare come in tempi moderni per caricare la pagina!

7

L'associazione bidirezionale è limitata quasi esclusivamente agli elementi che utilizzano ng-model. La direzione che va dalla vista al modello utilizza i gestori di eventi standard per rilevare le modifiche che devono essere aggiornate all'interno del modello (ad es., onchange). La direzione che va dal modello alla vista viene aggiornata durante lo $digest. Ma non chiamiamo direttamente il numero $digest.

Ogni elemento presente nella pagina che risponderà al ciclo di digest assegnerà, da qualche parte, un listener e un'espressione al suo ambito utilizzando $watch. Quando si scrive {{ foo() }} o quando si utilizza ng-model='user.name', internamente viene effettuata una chiamata a $watch effettuata per conto dell'utente con un'espressione Javascript che verrà eseguita ogni volta che viene eseguito un ciclo di digest.Questa registrazione potrebbe avvenire durante la compilazione del modello (il nostro primo esempio), oppure potrebbe accadere durante la fase di collegamento di una direttiva (la nostra seconda).

Non c'è magia qui. Gli ascoltatori collegati sono funzioni regolari: nel nostro esempio, l'ascoltatore per l'espressione foo() viene fornito per te e aggiornerà il testo html sulla pagina, mentre l'ascoltatore per l'espressione user.name chiamerà setText o setOption, o qualunque cosa sia richiesta dal particolare input che è stato allegato a ng-model.

Mentre angolare è in grado di gestire la maggior parte dell'ascolto, è possibile collegare manualmente le proprie espressioni dell'orologio con i propri ascoltatori all'interno di qualsiasi funzione che abbia accesso a un ambito (lo scopo è importante perché abbatteremo quegli osservatori se le parti corrispondenti di la pagina è stata rimossa). Stai attento all'eccesso. I collegamenti non sono gratuiti e più cose sono vincolate, più lentamente la pagina risponderà. I collegamenti una tantum sono un modo per ridurre questo costo. L'utilizzo di $on con $emit e $broadcast è un altro.

Quindi quando viene chiamato digest? Non è certamente automatico. Se il ciclo di digest è in esecuzione, significa qualcuno da qualche parte chiamato $apply sul loro ambito o sull'ambito di base. ng-model allega i gestori che risponderanno ai normali eventi html e invieranno chiamate a $apply per conto dell'utente. Ma foo(), d'altro canto, non verrà mai chiamato fino a quando qualche altro bit di script chiama da qualche parte $apply. Fortunatamente, la maggior parte delle funzioni che componi per avvolgere angolarmente quelle funzioni con una chiamata a $apply, così spesso non devi effettuare la chiamata tu stesso (ad esempio, $timeout è avvolto con $apply, motivo per cui lo usiamo invece di setTimeout) . Ma se stavi usando qualcosa che non rientri nel campo angolare (una libreria di terze parti che si collega agli eventi), dovresti ricordarti di chiamare tu stesso lo $apply e, come sopra, puoi farlo manualmente chiamando lo $apply ovunque tu abbia accesso ad un ambito.

1

Per rendere possibile il binding di dati, AngularJS utilizza le API di $ watch per osservare le modifiche sull'ambito. AngularJS ha registrato osservatori per ciascuna variabile sull'oscilloscopio per osservare il valore in essa contenuto. Se il valore della variabile sull'oscilloscopio viene modificato, la vista viene aggiornata automaticamente.

Succede perché il ciclo $ digest è attivato. Pertanto, AngularJS elabora tutti gli osservatori registrati nell'ambito corrente e i bambini e controlla gli aggiornamenti e chiama gli ascoltatori di watcher dedicati fino a quando il modello non si è stabilizzato e non vengono sparati più ascoltatori. Una volta che il ciclo $ digest termina l'esecuzione, il browser esegue nuovamente il rendering del DOM e riflette le modifiche

Per impostazione predefinita, ogni variabile su un oscilloscopio viene osservata dall'angolare. In questo modo, anche le variabili non necessarie vengono osservate dall'angolazione che richiede molto tempo e di conseguenza la pagina sta diventando lenta.

Problemi correlati