Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
feat($compile): add support for $observer deregistration
Browse files Browse the repository at this point in the history
In order to make the behavior compatible with $rootScope.$watch and $rootScope.$on methods, and
make it possible to deregister an attribute observer, Attributes.$observe method now returns a
deregistration function instead of the observer itself.

BREAKING CHANGE: calling attr.$observe no longer returns the observer function, but a
    deregistration function instead.

    To migrate the code follow the example below:

    Before:

```
    directive('directiveName', function() {
      return {
        link: function(scope, elm, attr) {
          var observer = attr.$observe('someAttr', function(value) {
            console.log(value);
          });
        }
      };
    });
```

    After:

```
    directive('directiveName', function() {
      return {
        link: function(scope, elm, attr) {
          var observer = function(value) {
            console.log(value);
          };

          attr.$observe('someAttr', observer);
        }
      };
    });
```

Closes #5609
  • Loading branch information
caiotoon authored and IgorMinar committed Mar 18, 2014
1 parent 78057a9 commit 299b220
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 5 deletions.
7 changes: 5 additions & 2 deletions src/ng/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
* @param {function(interpolatedValue)} fn Function that will be called whenever
the interpolated value of the attribute changes.
* See the {@link guide/directive#Attributes Directives} guide for more info.
* @returns {function()} the `fn` parameter.
* @returns {function()} Returns a deregistration function for this observer.
*/
$observe: function(key, fn) {
var attrs = this,
Expand All @@ -789,7 +789,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
fn(attrs[key]);
}
});
return fn;

return function() {
arrayRemove(listeners, fn);
};
}
};

Expand Down
17 changes: 14 additions & 3 deletions test/ng/compileSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1914,15 +1914,14 @@ describe('$compile', function() {


describe('interpolation', function() {
var observeSpy, directiveAttrs;
var observeSpy, directiveAttrs, deregisterObserver;

beforeEach(module(function() {
directive('observer', function() {
return function(scope, elm, attr) {
directiveAttrs = attr;
observeSpy = jasmine.createSpy('$observe attr');

expect(attr.$observe('someAttr', observeSpy)).toBe(observeSpy);
deregisterObserver = attr.$observe('someAttr', observeSpy);
};
});
directive('replaceSomeAttr', valueFn({
Expand Down Expand Up @@ -2020,6 +2019,18 @@ describe('$compile', function() {
}));


it('should return a deregistration function while observing an attribute', inject(function($rootScope, $compile) {
$compile('<div some-attr="{{value}}" observer></div>')($rootScope);

$rootScope.$apply('value = "first-value"');
expect(observeSpy).toHaveBeenCalledWith('first-value');

deregisterObserver();
$rootScope.$apply('value = "new-value"');
expect(observeSpy).not.toHaveBeenCalledWith('new-value');
}));


it('should set interpolated attrs to initial interpolation value', inject(function($rootScope, $compile) {
$rootScope.whatever = 'test value';
$compile('<div some-attr="{{whatever}}" observer></div>')($rootScope);
Expand Down

0 comments on commit 299b220

Please sign in to comment.