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.

+3


source to share


2 answers


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:

enter image description here



As you can see, this will throw an error in the library jQuery

:

enter image description here

this

has no function empty

, so it will throw a silent exception and will not work as expected.

+1


source


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.

-1


source







All Articles