Ricerca…


Sintassi

  • $ scope. $ watch (watchExpression, callback, [deep compare])
  • $ Portata. $ Digest ()
  • $ Portata. $ Applicare ([exp])

associazione dati bidirezionale

Angolare ha un po 'di magia sotto il suo cappuccio. abilita il DOM vincolante a variabili js reali.

Angular utilizza un ciclo, denominato " ciclo digest ", che viene chiamato dopo ogni modifica di una variabile, chiamando callback che aggiornano il DOM.

Ad esempio, la direttiva ng-model allega un eventup di keyup a questo input:

<input ng-model="variable" />

Ogni volta che si keyup evento keyup , viene keyup il ciclo digest .

Ad un certo punto, il ciclo digest itera su un callback che aggiorna il contenuto di questo intervallo:

<span>{{variable}}</span>

Il ciclo di vita di base di questo esempio, riassume (molto schematicamente) come funziona l'angolare:

  1. Scansioni angolari html
    • direttiva ng-model crea un listener keyup sull'input
    • expression inside span aggiunge un callback al ciclo digest
  2. L'utente interagisce con l'input
    • ascoltatore di keyup inizia il ciclo di digestione
    • il ciclo di digest chiama il callback
    • Gli aggiornamenti del callback comprendono i contenuti

$ digest e $ watch

L'implementazione del binding dei dati a due vie, per ottenere il risultato dell'esempio precedente, potrebbe essere eseguita con due funzioni principali:

  • $ digest è chiamato dopo un'interazione dell'utente (vincolante DOM => variabile)
  • $ watch imposta un callback da chiamare dopo le modifiche alle variabili (binding variable => DOM)

nota: questo è un esempio è una dimostrazione, non il codice angolare reale


<input id="input"/>
<span id="span"></span>

Le due funzioni di cui abbiamo bisogno:

var $watches = [];
function $digest(){
    $watches.forEach(function($w){
        var val = $w.val();
        if($w.prevVal !== val){
            $w.callback(val, $w.prevVal);
            $w.prevVal = val;
        }
    })
}
function $watch(val, callback){
    $watches.push({val:val, callback:callback, prevVal: val() })
}

Ora potremmo usare queste funzioni per collegare una variabile al DOM (l'angolare viene fornito con direttive incorporate che faranno questo per voi):

var realVar;    
//this is usually done by ng-model directive
input1.addEventListener('keyup',function(e){
    realVar=e.target.value; 
    $digest()
}, true);

//this is usually done with {{expressions}} or ng-bind directive
$watch(function(){return realVar},function(val){
    span1.innerHTML = val;
});

Fuori rotta, le implementazioni reali sono più complesse e supportano parametri come l' elemento a cui legarsi e quale variabile utilizzare

Un esempio in esecuzione può essere trovato qui: https://jsfiddle.net/azofxd4j/

l'albero $ scope

L'esempio precedente è abbastanza buono quando è necessario associare un singolo elemento html a una singola variabile.

In realtà, abbiamo bisogno di legare molti elementi a molte variabili:

<span ng-repeat="number in [1,2,3,4,5]">{{number}}</span>

Questa ng-repeat lega 5 elementi a 5 variabili chiamate number , con un valore diverso per ognuna di esse!


Il modo in cui l'angolare raggiunge questo comportamento sta usando un contesto separato per ogni elemento che ha bisogno di variabili separate. Questo contesto è chiamato scope.

Ogni ambito contiene proprietà, che sono le variabili legate al DOM, e le funzioni $digest e $watch sono implementate come metodi dell'ambito.

Il DOM è un albero e le variabili devono essere utilizzate in diversi livelli dell'albero:

<div>
    <input ng-model="person.name" />
    <span ng-repeat="number in [1,2,3,4,5]">{{number}} {{person.name}}</span>
</div>

Ma come abbiamo visto, il contesto (o l'ambito) delle variabili all'interno di ng-repeat è diverso dal contesto sopra di esso. Per risolvere questo - gli ambiti angolari implementa un albero.

Ogni ambito ha una serie di figli, e chiamando i suoi $digest metodo verrà eseguito tutti i dei suoi figli $digest metodo.

In questo modo - dopo aver modificato l'input - viene chiamato $digest per l'ambito div, che quindi esegue $digest per i suoi 5 figli - che aggiornerà il suo contenuto.


Un'implementazione semplice per un ambito potrebbe essere simile a questa:

function $scope(){
    this.$children = [];
    this.$watches = [];
}

$scope.prototype.$digest = function(){
    this.$watches.forEach(function($w){
        var val = $w.val();
        if($w.prevVal !== val){
            $w.callback(val, $w.prevVal);
          $w.prevVal = val;
        }
    });
    this.$children.forEach(function(c){
        c.$digest();
    });
}

$scope.prototype.$watch = function(val, callback){
    this.$watches.push({val:val, callback:callback, prevVal: val() })
}

nota: questo è un esempio è una dimostrazione, non il codice angolare reale



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow