AngularJS
Comment fonctionne la liaison de données
Recherche…
Remarques
Donc, bien que ce concept de liaison de données soit dans l’ensemble facile pour le développeur, il est assez lourd pour le navigateur puisque Angular écoute tous les changements d’événements et exécute le cycle Digest. Pour cette raison, chaque fois que nous attachons un modèle à la vue, assurez-vous que Scope est aussi optimisé que possible.
Exemple de liaison de données
<p ng-bind="message"></p>
Ce "message" doit être associé à la portée du contrôleur d'éléments en cours.
$scope.message = "Hello World";
Plus tard, même si le modèle de message est mis à jour, cette valeur mise à jour est reflétée dans l'élément HTML. Lorsque angular compile, le template "Hello World" sera attaché à innerHTML du monde actuel. Angular maintient un mécanisme de surveillance de toutes les directives attachées à la vue. Il a un mécanisme de cycle de digestion où il itère à travers le tableau Watchers, il mettra à jour l'élément DOM s'il y a un changement dans la valeur précédente du modèle.
Il n'y a pas de vérification périodique de Scope s'il y a un changement dans les objets qui lui sont attachés. Tous les objets attachés à la portée ne sont pas surveillés. Scope maintient prototypiquement un $$ WatchersArray . Scope ne parcourt que cet objet WatchersArray lorsque $ digest est appelé.
Angular ajoute un observateur au WatchersArray pour chacun de ces
- {{expression}} - Dans vos modèles (et partout où il y a une expression) ou lorsque nous définissons ng-model.
- $ scope. $ watch ('expression / function') - Dans votre JavaScript, nous pouvons simplement attacher un objet scope à angular à regarder.
La fonction $ watch prend en trois paramètres:
- La première est une fonction d'observation qui renvoie simplement l'objet ou nous pouvons simplement ajouter une expression.
- La seconde est une fonction d'écoute qui sera appelée en cas de changement d'objet. Toutes les choses comme les modifications DOM seront implémentées dans cette fonction.
- Le troisième étant un paramètre facultatif qui prend un booléen. Si c'est vrai, la profondeur angulaire regarde l'objet et si son faux Angular fait juste une référence en regardant l'objet. La mise en œuvre brutale de $ watch ressemble à ceci
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
};
Il y a une chose intéressante dans Angular appelé Digest Cycle. Le cycle $ digest commence à la suite d'un appel à $ scope. $ Digest (). Supposons que vous modifiez un modèle $ scope dans une fonction de gestionnaire via la directive ng-click. Dans ce cas, AngularJS déclenche automatiquement un cycle $ digest en appelant $ digest (). En plus de ng-click, il existe plusieurs autres directives / services intégrés qui vous permettent de changer de modèle (par exemple, ng-model, $ timeout, etc.) et déclenche automatiquement un cycle de digestion. L'implémentation brute de $ digest ressemble à ceci.
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;
};
Si nous utilisons la fonction setTimeout () de JavaScript pour mettre à jour un modèle de portée, Angular n'a aucun moyen de savoir ce que vous pourriez changer. Dans ce cas, il est de notre responsabilité d'appeler manuellement $ apply (), ce qui déclenche un cycle $ digest. De même, si vous avez une directive qui configure un écouteur d'événement DOM et modifie certains modèles à l'intérieur de la fonction de gestionnaire, vous devez appeler $ apply () pour vous assurer que les modifications prennent effet. La grande idée de $ apply est que nous pouvons exécuter du code qui n’est pas au courant d’Angular, ce code pouvant encore changer les choses sur la portée. Si nous encapsulons ce code dans $ apply, il se chargera d'appeler $ digest (). Implémentation approximative de $ apply ().
Scope.prototype.$apply = function(expr) {
try {
return this.$eval(expr); //Evaluating code in the context of Scope
} finally {
this.$digest();
}
};