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

Commit fe8d893

Browse files
tleruitteIgorMinar
authored andcommitted
feat($compile): allow directives to modify interpolated attributes
A directive can now set/update/remove attribute values even those containing interpolation during the compile phase and have the new value be picked up during the compilation. For example in template: <div replace-directive some-attr-or-directive="{{originalInterpolationValue}}"></div> the replace-directive can now replace the value of some-attr-or-directive during compilation which produces this intermitent template: <div replace-directive some-attr-or-directive="{{replacedInterpolationValue}}"></div> or even <div replace-directive some-attr-or-directive="replacedStaticValue"></div> as well as <div replace-directive some-attr-or-directive></div>
1 parent eb53423 commit fe8d893

File tree

2 files changed

+22
-6
lines changed

2 files changed

+22
-6
lines changed

src/ng/compile.js

+8-6
Original file line numberDiff line numberDiff line change
@@ -1102,11 +1102,13 @@ function $CompileProvider($provide) {
11021102
compile: valueFn(function attrInterpolateLinkFn(scope, element, attr) {
11031103
var $$observers = (attr.$$observers || (attr.$$observers = {}));
11041104

1105-
if (name === 'class') {
1106-
// we need to interpolate classes again, in the case the element was replaced
1107-
// and therefore the two class attrs got merged - we want to interpolate the result
1108-
interpolateFn = $interpolate(attr[name], true);
1109-
}
1105+
// we need to interpolate again, in case the attribute value has been updated
1106+
// (e.g. by another directive's compile function)
1107+
interpolateFn = $interpolate(attr[name], true);
1108+
1109+
// if attribute was updated so that there is no interpolation going on we don't want to
1110+
// register any observers
1111+
if (!interpolateFn) return;
11101112

11111113
attr[name] = interpolateFn(scope);
11121114
($$observers[name] || ($$observers[name] = [])).$$inter = true;
@@ -1203,7 +1205,7 @@ function directiveNormalize(name) {
12031205
* @param {string} name Normalized element attribute name of the property to modify. The name is
12041206
* revers translated using the {@link ng.$compile.directive.Attributes#$attr $attr}
12051207
* property to the original name.
1206-
* @param {string} value Value to set the attribute to.
1208+
* @param {string} value Value to set the attribute to. The value can be an interpolated string.
12071209
*/
12081210

12091211

test/ng/compileSpec.js

+14
Original file line numberDiff line numberDiff line change
@@ -1503,6 +1503,12 @@ describe('$compile', function() {
15031503
expect(attr.$observe('someAttr', observeSpy)).toBe(observeSpy);
15041504
};
15051505
});
1506+
directive('replaceSomeAttr', valueFn({
1507+
compile: function(element, attr) {
1508+
attr.$set('someAttr', 'bar-{{1+1}}');
1509+
expect(element).toBe(attr.$$element);
1510+
}
1511+
}));
15061512
}));
15071513

15081514

@@ -1544,6 +1550,14 @@ describe('$compile', function() {
15441550
}));
15451551

15461552

1553+
it('should allow directive to replace interpolated attributes before attr interpolation compilation', inject(
1554+
function($compile, $rootScope) {
1555+
element = $compile('<div some-attr="foo-{{1+1}}" replace-some-attr></div>')($rootScope);
1556+
$rootScope.$digest();
1557+
expect(element.attr('some-attr')).toEqual('bar-2');
1558+
}));
1559+
1560+
15471561
it('should call observer of non-interpolated attr through $evalAsync',
15481562
inject(function($rootScope, $compile) {
15491563
$compile('<div some-attr="nonBound" observer></div>')($rootScope);

0 commit comments

Comments
 (0)