AngularJS
Jak działa wiązanie danych
Szukaj…
Uwagi
Tak więc, choć ogólnie ta koncepcja wiązania danych jest łatwa dla programisty, jest dość ciężka dla przeglądarki, ponieważ Angular nasłuchuje każdej zmiany zdarzenia i uruchamia cykl podsumowania. Z tego powodu, za każdym razem, gdy dołączamy jakiś model do widoku, upewnij się, że zakres jest jak najbardziej zoptymalizowany
Przykład powiązania danych
<p ng-bind="message"></p>
Ten „komunikat” musi zostać dołączony do zakresu kontrolera aktualnych elementów.
$scope.message = "Hello World";
W późniejszym czasie, nawet jeśli model komunikatu zostanie zaktualizowany, ta zaktualizowana wartość zostanie odzwierciedlona w elemencie HTML. Podczas kompilacji kątowej szablon „Hello World” zostanie dołączony do innerHTML bieżącego świata. Angular utrzymuje mechanizm obserwacyjny wszystkich dyrektyw dołączonych do widoku. Ma mechanizm cyklu trawienia, w którym iteruje się przez tablicę Obserwatorów, zaktualizuje element DOM, jeśli nastąpi zmiana poprzedniej wartości modelu.
Nie ma okresowego sprawdzania zakresu, czy istnieje jakaś zmiana w dołączonych do niego obiektach. Nie wszystkie obiekty dołączone do lunety są obserwowane. Zakres prototypowo utrzymuje $$ WatchersArray . Zakres iteruje tylko przez tę Tablicę Obserwatorów, gdy wywoływane jest $ digest.
Angular dodaje obserwatora do WatchersArray dla każdego z nich
- {{expression}} - W twoich szablonach (i gdziekolwiek indziej, gdzie jest wyrażenie) lub gdy definiujemy ng-model.
- $ scope. $ watch ('wyrażenie / funkcja') - W twoim JavaScript możemy po prostu dołączyć obiekt zakresu do obserwacji kątowej.
Funkcja $ watch przyjmuje trzy parametry:
- Pierwszy to funkcja obserwatora, która po prostu zwraca obiekt lub możemy po prostu dodać wyrażenie.
- Drugi to funkcja detektora, która zostanie wywołana, gdy nastąpi zmiana w obiekcie. Wszystkie rzeczy takie jak zmiany DOM zostaną zaimplementowane w tej funkcji.
- Trzeci jest parametrem opcjonalnym, który przyjmuje wartość logiczną. Jeśli to prawda, kątowe głębokie obserwuje obiekt, a jeśli jego fałszywe kątowe po prostu ogląda obiekt referencyjny. Rough Implementacja $ watch wygląda następująco
Scope.prototype.$watch = function(watchFn, listenerFn) {
var watcher = {
watchFn: watchFn,
listenerFn: listenerFn || function() { },
last: initWatchVal // initWatchVal is typically undefined
};
this.$$watchers.push(watcher); // pushing the Watcher Object to Watchers
};
W Angular jest interesująca rzecz o nazwie Cykl trawienny. Cykl $ digest rozpoczyna się w wyniku wywołania $ scope. $ Digest (). Załóżmy, że zmieniasz model $ scope w funkcji modułu obsługi poprzez dyrektywę ng-click. W takim przypadku AngularJS automatycznie uruchamia cykl $ digest przez wywołanie $ digest (). Oprócz ng-click istnieje kilka innych wbudowanych dyrektyw / usług, które pozwalają zmieniać modele (np. Ng-model, $ limit czasu itp.) i automatycznie uruchamia cykl $ streszczenia. Z grubsza implementacja $ digest wygląda następująco.
Scope.prototype.$digest = function() {
var dirty;
do {
dirty = this.$$digestOnce();
} while (dirty);
}
Scope.prototype.$$digestOnce = function() {
var self = this;
var newValue, oldValue, dirty;
_.forEach(this.$$watchers, function(watcher) {
newValue = watcher.watchFn(self);
oldValue = watcher.last; // It just remembers the last value for dirty checking
if (newValue !== oldValue) { //Dirty checking of References
// For Deep checking the object , code of Value
// based checking of Object should be implemented here
watcher.last = newValue;
watcher.listenerFn(newValue,
(oldValue === initWatchVal ? newValue : oldValue),
self);
dirty = true;
}
});
return dirty;
};
Jeśli użyjemy funkcji setTimeout () JavaScript do aktualizacji modelu zakresu, Angular nie będzie wiedział, co możesz zmienić. W takim przypadku naszym obowiązkiem jest ręczne wywołanie $ Apply (), co uruchomi cykl skrótu $. Podobnie, jeśli masz dyrektywę, która konfiguruje detektor zdarzeń DOM i zmienia niektóre modele wewnątrz funkcji modułu obsługi, musisz wywołać $ Apply (), aby zmiany zostały wprowadzone. Główną ideą $ Apply jest to, że możemy wykonać kod, który nie jest świadomy Angulara, a kod ten może wciąż zmieniać rzeczy w zakresie. Jeśli zawiniemy ten kod w $ apply, zajmie się wywołaniem $ digest (). Szorstka implementacja $ apply ().
Scope.prototype.$apply = function(expr) {
try {
return this.$eval(expr); //Evaluating code in the context of Scope
} finally {
this.$digest();
}
};