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

Commit 0728cc2

Browse files
committed
fix($compile): allow directives to have decorators
Allow directives to have decorators that modify the directive `scope` property Close: #10149
1 parent ece293a commit 0728cc2

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
@@ -851,13 +851,18 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
851851
// The assumption is that future DOM event attribute names will begin with
852852
// 'on' and be composed of only English letters.
853853
var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;
854+
var bindingCache = createMap();
854855

855856
function parseIsolateBindings(scope, directiveName, isController) {
856857
var LOCAL_REGEXP = /^\s*([@&<]|=(\*?))(\??)\s*(\w*)\s*$/;
857858

858859
var bindings = {};
859860

860861
forEach(scope, function(definition, scopeName) {
862+
if (definition in bindingCache) {
863+
bindings[scopeName] = bindingCache[definition];
864+
return;
865+
}
861866
var match = definition.match(LOCAL_REGEXP);
862867

863868
if (!match) {
@@ -875,6 +880,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
875880
optional: match[3] === '?',
876881
attrName: match[4] || scopeName
877882
};
883+
if (match[4]) {
884+
bindingCache[definition] = bindings[scopeName];
885+
}
878886
});
879887

880888
return bindings;
@@ -967,11 +975,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
967975
directive.name = directive.name || name;
968976
directive.require = directive.require || (directive.controller && directive.name);
969977
directive.restrict = directive.restrict || 'EA';
970-
var bindings = directive.$$bindings =
971-
parseDirectiveBindings(directive, directive.name);
972-
if (isObject(bindings.isolateScope)) {
973-
directive.$$isolateBindings = bindings.isolateScope;
974-
}
975978
directive.$$moduleName = directiveFactory.$$moduleName;
976979
directives.push(directive);
977980
} catch (e) {
@@ -2545,6 +2548,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
25452548
if (startAttrName) {
25462549
directive = inherit(directive, {$$start: startAttrName, $$end: endAttrName});
25472550
}
2551+
if (!directive.$$bindings) {
2552+
var bindings = directive.$$bindings =
2553+
parseDirectiveBindings(directive, directive.name);
2554+
if (isObject(bindings.isolateScope)) {
2555+
directive.$$isolateBindings = bindings.isolateScope;
2556+
}
2557+
}
25482558
tDirectives.push(directive);
25492559
match = directive;
25502560
}

test/ng/compileSpec.js

+45
Original file line numberDiff line numberDiff line change
@@ -8112,6 +8112,51 @@ describe('$compile', function() {
81128112
});
81138113
});
81148114

8115+
8116+
it('should be possible to change the scope of a directive using $provide', function() {
8117+
module(function($provide) {
8118+
directive('foo', function() {
8119+
return {
8120+
scope: {},
8121+
template: '<div></div>'
8122+
};
8123+
});
8124+
$provide.decorator('fooDirective', function($delegate) {
8125+
var directive = $delegate[0];
8126+
directive.scope.something = '=';
8127+
directive.template = '<span>{{something}}</span>';
8128+
return $delegate;
8129+
});
8130+
});
8131+
inject(function($compile, $rootScope) {
8132+
element = $compile('<div><div foo something="bar"></div></div>')($rootScope);
8133+
$rootScope.bar = 'bar';
8134+
$rootScope.$digest();
8135+
expect(element.text()).toBe('bar');
8136+
});
8137+
});
8138+
8139+
8140+
it('should distinguish different bindings with the same binding name', function() {
8141+
module(function() {
8142+
directive('foo', function() {
8143+
return {
8144+
scope: {
8145+
foo: '=',
8146+
bar: '='
8147+
},
8148+
template: '<div><div>{{foo}}</div><div>{{bar}}</div></div>'
8149+
};
8150+
});
8151+
});
8152+
inject(function($compile, $rootScope) {
8153+
element = $compile('<div><div foo="\'foo\'" bar="\'bar\'"></div></div>')($rootScope);
8154+
$rootScope.$digest();
8155+
expect(element.text()).toBe('foobar');
8156+
});
8157+
});
8158+
8159+
81158160
it('should safely create transclude comment node and not break with "-->"',
81168161
inject(function($rootScope) {
81178162
// see: https://github.com/angular/angular.js/issues/1740

0 commit comments

Comments
 (0)