Writing Robust AngularJS Web Applications
The idea behind AngularJS model-changes tracking mechanism is based on the
observation that at the end of the day, there is a finite (and rather small) number
of situations where models can change. Those include:
- DOM events (user changing value of an input field, clicking on a button
to invoke a JavaScript function and so on) - XHR responses firing callbacks
- Browser's location changes
- Timers (setTimout, setInterval) firing the callbacks
Indeed, if none of the earlier events take place (user is not interacting with a page,
no XHR calls have finished, no timers firing) there is no point in monitoring the
model for changes. There is simply nothing going on for a given page, the model
isn't changing, so there is no reason to re-render the DOM.
AngularJS starts its model-observing machinery if and only if it is explicitly told to
do so. To bring this sophisticated mechanism to life we need to execute the $apply
method on a scope object.
Going back to our simple-model directive example we could do it after each and
every change to the input's value (so model changes are propagated after each
keystroke. T his is how the ng-model directive behaves by default):
.directive('simpleModel', function ($parse) {
return function (scope, element, attrs) {
var modelGetter = $parse(attrs.simpleModel);
var modelSetter = modelGetter.assign;
//Model -> DOM updates
scope.$watch(modelGetter, function(newVal, oldVal){
element.val(newVal);
});
//DOM -> Model updates
element.bind('input', function () {
scope.$apply(function () {
modelSetter(scope, element.val());
});
});
};
})