Passing jqLite.html () is handled directly as AngularJS clock listener
I am trying to pass the jqLite element.html function directly as an observer listener:
angular.module('testApp', []).directive('test', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
scope.$watch('someVariable', element.html); // <-- Passing the function handle as listener
}
};
});
However, this doesn't work for some reason, so as a workaround, I wrapped the listener in a function:
angular.module('testApp', []).directive('test', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
scope.$watch('someVariable', function (newValue) {
element.html(newValue);
});
}
};
});
This second example works.
I don't understand why the first example is broken. Any ideas?
EDIT: I forgot to mention, the browser doesn't give me any errors. It just shows me an empty item.
source to share
Actually, because of the angular injector that automatically changes the this
function property , consider this:
var test = function(string) {
return {
html: function(value) {
console.log(this);
}
}
}
$scope.$watch('my_watch_expression', test('string').html);
when you check the value this
, this is what you get:
As you can see, this will throw an error in the library jQuery
:
this
has no function empty
, so it will throw a silent exception and will not work as expected.
source to share
In the official docs https://docs.angularjs.org/api/ng/type/ $ rootScope.Scope # $ watch
the second parameter in $ watch is the listener
"The listener is called only when the value ..."
logically, if the listener is "called" it must be a function ... or maybe I'm wrong here.
when you do:
link: function (scope, element, attrs) {
scope.$watch('someVariable', element.html); // <-- Passing the function handle as listener
}
it looks at the element passed in the link function and tries to access the .html attribute. It might be a function, but it returns a string ... hence it succeeds but does not execute any entries, since the equivalent would look something like this:
scope.$watch('someVariable', "<div> some content </div>");
Which won't do anything, but doesn't throw any errors.
And if you wrap it in a function like you do, then you can do something with it.
source to share