Skip to content

Commit

Permalink
fix ($compile): keep prototype properties for template URL directives
Browse files Browse the repository at this point in the history
Previously, if a directive definition object was defined with methods like `compile`
provided on the prototype rather than the instance, the Angular compiler failed
to use these methods when the directive had a `templateURL`. This change ensures
that these prototypical methods are not lost.

This enables developers to define their directives using "classes" such as
in CoffeeScript or ES6.

Closes angular#10926
  • Loading branch information
hannahhoward authored and petebacondarwin committed Feb 2, 2015
1 parent 0d42426 commit 6c6a408
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 2 deletions.
3 changes: 1 addition & 2 deletions src/ng/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -2155,8 +2155,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
afterTemplateChildLinkFn,
beforeTemplateCompileNode = $compileNode[0],
origAsyncDirective = directives.shift(),
// The fact that we have to copy and patch the directive seems wrong!
derivedSyncDirective = extend({}, origAsyncDirective, {
derivedSyncDirective = inherit(origAsyncDirective, {
templateUrl: null, transclude: null, replace: null, $$originalDirective: origAsyncDirective
}),
templateUrl = (isFunction(origAsyncDirective.templateUrl))
Expand Down
49 changes: 49 additions & 0 deletions test/ng/compileSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,29 @@ describe('$compile', function() {
expect(element.find('p').text()).toBe('Hello, world!');
});
});

it('should keep prototype properties on directive', function() {
module(function() {
function DirectiveClass() {
this.restrict = 'E';
this.template = "<p>{{value}}</p>";
}

DirectiveClass.prototype.compile = function() {
return function(scope, element, attrs) {
scope.value = "Test Value";
};
};

directive('templateUrlWithPrototype', valueFn(new DirectiveClass()));
});

inject(function($compile, $rootScope) {
element = $compile('<template-url-with-prototype><template-url-with-prototype>')($rootScope);
$rootScope.$digest();
expect(element.find("p")[0].innerHTML).toEqual("Test Value");
});
});
});


Expand Down Expand Up @@ -2028,6 +2051,32 @@ describe('$compile', function() {
});
});

it('should keep prototype properties on sync version of async directive', function() {
module(function() {
function DirectiveClass() {
this.restrict = 'E';
this.templateUrl = "test.html";
}

DirectiveClass.prototype.compile = function() {
return function(scope, element, attrs) {
scope.value = "Test Value";
};
};

directive('templateUrlWithPrototype', valueFn(new DirectiveClass()));
});

inject(function($compile, $rootScope, $httpBackend) {
$httpBackend.whenGET('test.html').
respond('<p>{{value}}</p>');
element = $compile('<template-url-with-prototype><template-url-with-prototype>')($rootScope);
$httpBackend.flush();
$rootScope.$digest();
expect(element.find("p")[0].innerHTML).toEqual("Test Value");
});
});

});


Expand Down

0 comments on commit 6c6a408

Please sign in to comment.