Reputation: 3132
Below is my understanding of how binding happens in angularJS. Would be great if experts can provide feedback/comment..
<div ng-controller="ctrlA">
{{myvar}}
{{anothervar}}
</div>
$scope.watch( function (scope) {
return scope.anothervar;
} , function (oldValue, newValue) {
// code to manupilate HTML with new value!!
});
$scope.watch( function (scope) {
return scope.myVar;
} , function (oldValue, newValue) {
// code to manipulate HTML with new value!!
});
As soon as angularJS encounters {{myVar}} (and {{anothervar}}) a watcher (for each variable) is created internally. This watcher is created for $scope of controller 'ctrlA'.
Whenever functions are called within $timeout, ng-click etc they are embedded within $scope.apply(). After your function is executed (which might change some scope variables), $apply will call digest on the rootScope. This will sync variables throughout the app with the UI!
When $scope.digest is called it iterates through all the watchers for that scope. It then gets the current value of the variable and checks to see if it changed. If it changed it calls the watcher handler (which changes the html to reflect the new value!).
I have a question here. Does angularJS store have some kind of key-map (or some data structure) for every scope, which contains the reference to watcher and the current value for that watcher?? Something like:
watch ref (for myvar) -> current value (of myvar)
watch ref (for anothervar) -> current value (of anothervar)
Upvotes: 4
Views: 334
Reputation:
Your understanding of how Angular sets up a watcher for each binding is pretty much right on the money. I'll go ahead and jump straight to the question, as opposed to debunking/discussing your point of view of what the inner workings of Angular bindings look like.
I have a question here. Does angularJS store have some kind of key-map (or some data structure) for every scope, which contains the reference to watcher and the current value for that watcher??
$scope
has an internal array of currently active watchers (.$$watchers
) attached to said scope, where an entry would look as such:
The explanation below is wrong. See my edit for correction(s)
eq
is a boolean dictating whether the expression in fn
holds
true/false.exp
is the raw string value that you exposed in your view between the 'squiggles' {{raw_expr_value}}
. fn
is a reference to the internal $interpolate.$$watchDelegate (or as you put it, "a reference to the watcher"). If this were a manual $scope.$watch('val', _func_)
, fn
would be a reference to _func_
.get
I'm not so sure about. If anyone could fill in on what this is, that'd be super.last
is the latest value the expression evaluated to.With all of that said, ordinarily you shouldn't be touching the internal $$
variables, but if you must - go right ahead. Tread lightly :)
I was in the wrong. Looking at the source of $watch
, the properties are as follows:
fn
- the callback function for your watcher.last
- src a unique value applied at the very beginning of the setup of $watch
. Probably so as to trigger the expression to evaluate initially. get
- The expression wrapped with $parse()
. exp
- prettyPrintExpression which is something I have never heard about before. Falls back to the watched expression in your view / $watch
handler.eq
- This is where I was oh so very wrong. The boolean dictates whether we're doing a deep watch (object equality) or a regular shallow watch.Upvotes: 0