AngularJS
Hoe gegevensbinding werkt
Zoeken…
Opmerkingen
Hoewel dit concept van gegevensbinding in het algemeen eenvoudig is voor de ontwikkelaar, is het behoorlijk zwaar voor de browser, omdat Angular naar elke gebeurteniswijziging luistert en de Digest Cycle uitvoert. Daarom moet u, wanneer we een model aan de weergave koppelen, ervoor zorgen dat Scope zo optimaal mogelijk is
Voorbeeld gegevensbinding
<p ng-bind="message"></p>
Dit 'bericht' moet worden toegevoegd aan het bereik van de huidige elementencontroller.
$scope.message = "Hello World";
Op een later tijdstip, zelfs als het berichtmodel wordt bijgewerkt, wordt die bijgewerkte waarde weerspiegeld in het HTML-element. Wanneer angular wordt gecompileerd, wordt de sjabloon "Hallo wereld" aan de innerHTML van de huidige wereld toegevoegd. Angular onderhoudt een Watch-mechanisme van alle richtlijnen die aan het zicht zijn gekoppeld. Het heeft een Digest Cycle-mechanisme waar het door de Watchers-reeks wordt herhaald, het zal het DOM-element bijwerken als er een wijziging is in de vorige waarde van het model.
Scope wordt niet periodiek gecontroleerd op enige wijziging in de objecten die eraan zijn gekoppeld. Niet alle objecten die aan het bereik zijn gekoppeld, worden bekeken. Scope onderhoudt prototypisch een $$ WatchersArray . Scope doorzoekt deze WatchersArray alleen wanneer $ digest wordt aangeroepen.
Angular voegt voor elk van deze een watcher toe aan de WatchersArray
- {{expression}} - In uw sjablonen (en overal waar een expressie is) of wanneer we het ng-model definiëren.
- $ scope. $ watch ('expression / function') - In uw JavaScript kunnen we gewoon een scope-object toevoegen om te bekijken.
$ watch- functie heeft drie parameters:
- De eerste is een watcher-functie die het object retourneert of we kunnen gewoon een uitdrukking toevoegen.
- De tweede is een luisterfunctie die wordt aangeroepen wanneer het object wordt gewijzigd. Alle dingen zoals DOM-wijzigingen worden in deze functie geïmplementeerd.
- De derde is een optionele parameter die een Boolean opneemt. Als het waar is, kijkt hoekig diep naar het object en als zijn valse hoek gewoon een referentie doet die naar het object kijkt. Ruwe implementatie van $ watch ziet er zo uit
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
};
Er is iets interessants in Angular genaamd Digest Cycle. De $ digest-cyclus start als gevolg van een aanroep van $ scope. $ Digest (). Stel dat u een $ scope-model in een handlerfunctie wijzigt via de ng-click-instructie. In dat geval activeert AngularJS automatisch een $ digest-cyclus door $ digest () aan te roepen. Naast ng-click zijn er verschillende andere ingebouwde richtlijnen / services waarmee u modellen kunt wijzigen (bijv. Ng-model, $ timeout, enz.) en automatisch een $ digest-cyclus activeren. De ruwe implementatie van $ digest ziet er zo uit.
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;
};
Als we de functie setTimeout () van JavaScript gebruiken om een scoopmodel bij te werken, weet Angular niet wat u kunt veranderen. In dit geval is het onze verantwoordelijkheid om $ apply () handmatig aan te roepen, waardoor een $ digest-cyclus wordt geactiveerd. Evenzo, als u een richtlijn heeft die een DOM-gebeurtenislistener instelt en sommige modellen binnen de handlerfunctie wijzigt, moet u $ apply () aanroepen om ervoor te zorgen dat de wijzigingen van kracht worden. Het grote idee van $ apply is dat we een code kunnen uitvoeren die Angular niet kent, die code kan nog steeds dingen veranderen in de scope. Als we die code omsluiten in $ apply, zorgt het ervoor dat $ digest () wordt aangeroepen. Ruwe implementatie van $ apply ().
Scope.prototype.$apply = function(expr) {
try {
return this.$eval(expr); //Evaluating code in the context of Scope
} finally {
this.$digest();
}
};