2

Having read AngularJS : Difference between the $observe and $watch methods, and the implementation of ng-href/ng-src:

link: function(scope, element, attr) {
  attr.$observe(normalized, function(value) {
    if (!value)
      return;

    attr.$set(attrName, value);
    // ...
  }
}

I wonder why ng-href/ng-src are implemented by using attr.$observe instead of scope.$watch. By using scope.$watch, it looks like

link: function(scope, element, attr) {
  scope.$watch(attr[normalized], function(newValue) {
    // ...
  })
}

then in view we could write <img ng-href="expressionFoo"> instead of <img ng-href="{{ expressionFoo }}">.

The possible reasons I could figure out are

  1. attr.$observe makes a directive to work more like a normal DOM attribute. After link, I could affect the directive by attr.$set('ngHref', ...) in another directive.
  2. interpolate is higher level than expression. It's easier to write plain strings and multiple expressions by using interpolate.
  3. ng-href and ng-src both result in string attributes, so it's safe and easier to use interpolate hence attr.$observe here.

Any idea?

Community
  • 1
  • 1
okm
  • 23,575
  • 5
  • 83
  • 90

1 Answers1

1

I think the scope isn't what you think.

Option scope in directives is false by default, which means we get parent scope, that could be anything, really.

If we want to watch for element's attribute change, we have to watch the element's attribute "ng-blah". The scope is simply not related.

If we were to use scope.watch, we probably wouldn't even have a property named after that attribute, and nothing would work.

Ven
  • 19,015
  • 2
  • 41
  • 61