When using a primitive (string, boolean, number, etc), you can't reference it. When you use an object or array, you can reference and modify it's members.
That means, when you you do a
$scope.$watch('searchString', function(str, oldValue) {
console.log(str.length);
});
You are checking for the new length of searchString
, that MIGHT be null/undefined/empty when $watch
is first called and oldValue
will contain the current value. so if you are modifying searchString
from another scope or directive, it won't be affected, because the new scopes searchString
is the one being changed (that is, the current instance value). For it to effectively be changed where it was defined, you should use:
$scope.search = {input: ''};
$scope.$watch('search.input', function(str, oldValue) {
console.log(str.length);
});
http://plnkr.co/edit/EFdnhQE1nN5vsBJR1sEm?p=preview
And a brief explanation on $watch
: scope.$watch
will be called when the $digest
cycle has completed. if you change your data (primitives or even objects) from outside a non-angular event (like element.on('click' ...)
on jQuery), you must call $scope.$apply()
or $timeout
to reflect it on your UI. otherwise, from an ng-click
, or changes to a model from an input, your $digest
is called automatically, thus updating everything in real time. Some info about $scope and inheritance here https://stackoverflow.com/a/15645354/647380