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

Commit 77cdc37

Browse files
lgalfasoNarretz
authored andcommitted
fix($compile): allow directives to have decorators
Allow directives to have decorators that modify the directive `scope` property Close: #10149
1 parent ab95ba6 commit 77cdc37

File tree

2 files changed

+60
-5
lines changed

2 files changed

+60
-5
lines changed

src/ng/compile.js

+15-5
Original file line numberDiff line numberDiff line change
@@ -777,13 +777,18 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
777777
// The assumption is that future DOM event attribute names will begin with
778778
// 'on' and be composed of only English letters.
779779
var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;
780+
var bindingCache = createMap();
780781

781782
function parseIsolateBindings(scope, directiveName, isController) {
782783
var LOCAL_REGEXP = /^\s*([@&]|=(\*?))(\??)\s*(\w*)\s*$/;
783784

784785
var bindings = {};
785786

786787
forEach(scope, function(definition, scopeName) {
788+
if (definition in bindingCache) {
789+
bindings[scopeName] = bindingCache[definition];
790+
return;
791+
}
787792
var match = definition.match(LOCAL_REGEXP);
788793

789794
if (!match) {
@@ -801,6 +806,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
801806
optional: match[3] === '?',
802807
attrName: match[4] || scopeName
803808
};
809+
if (match[4]) {
810+
bindingCache[definition] = bindings[scopeName];
811+
}
804812
});
805813

806814
return bindings;
@@ -893,11 +901,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
893901
directive.name = directive.name || name;
894902
directive.require = directive.require || (directive.controller && directive.name);
895903
directive.restrict = directive.restrict || 'EA';
896-
var bindings = directive.$$bindings =
897-
parseDirectiveBindings(directive, directive.name);
898-
if (isObject(bindings.isolateScope)) {
899-
directive.$$isolateBindings = bindings.isolateScope;
900-
}
901904
directive.$$moduleName = directiveFactory.$$moduleName;
902905
directives.push(directive);
903906
} catch (e) {
@@ -2169,6 +2172,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
21692172
if (startAttrName) {
21702173
directive = inherit(directive, {$$start: startAttrName, $$end: endAttrName});
21712174
}
2175+
if (!directive.$$bindings) {
2176+
var bindings = directive.$$bindings =
2177+
parseDirectiveBindings(directive, directive.name);
2178+
if (isObject(bindings.isolateScope)) {
2179+
directive.$$isolateBindings = bindings.isolateScope;
2180+
}
2181+
}
21722182
tDirectives.push(directive);
21732183
match = directive;
21742184
}

test/ng/compileSpec.js

+45
Original file line numberDiff line numberDiff line change
@@ -7438,6 +7438,51 @@ describe('$compile', function() {
74387438
});
74397439
});
74407440

7441+
7442+
it('should be possible to change the scope of a directive using $provide', function() {
7443+
module(function($provide) {
7444+
directive('foo', function() {
7445+
return {
7446+
scope: {},
7447+
template: '<div></div>'
7448+
};
7449+
});
7450+
$provide.decorator('fooDirective', function($delegate) {
7451+
var directive = $delegate[0];
7452+
directive.scope.something = '=';
7453+
directive.template = '<span>{{something}}</span>';
7454+
return $delegate;
7455+
});
7456+
});
7457+
inject(function($compile, $rootScope) {
7458+
element = $compile('<div><div foo something="bar"></div></div>')($rootScope);
7459+
$rootScope.bar = 'bar';
7460+
$rootScope.$digest();
7461+
expect(element.text()).toBe('bar');
7462+
});
7463+
});
7464+
7465+
7466+
it('should distinguish different bindings with the same binding name', function() {
7467+
module(function() {
7468+
directive('foo', function() {
7469+
return {
7470+
scope: {
7471+
foo: '=',
7472+
bar: '='
7473+
},
7474+
template: '<div><div>{{foo}}</div><div>{{bar}}</div></div>'
7475+
};
7476+
});
7477+
});
7478+
inject(function($compile, $rootScope) {
7479+
element = $compile('<div><div foo="\'foo\'" bar="\'bar\'"></div></div>')($rootScope);
7480+
$rootScope.$digest();
7481+
expect(element.text()).toBe('foobar');
7482+
});
7483+
});
7484+
7485+
74417486
it('should safely create transclude comment node and not break with "-->"',
74427487
inject(function($rootScope) {
74437488
// see: https://github.com/angular/angular.js/issues/1740

0 commit comments

Comments
 (0)