aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ng/compile.js14
-rwxr-xr-xtest/ng/compileSpec.js56
2 files changed, 65 insertions, 5 deletions
diff --git a/src/ng/compile.js b/src/ng/compile.js
index 7d0bb008..a6bcc3e7 100644
--- a/src/ng/compile.js
+++ b/src/ng/compile.js
@@ -1400,7 +1400,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
optional = (match[2] == '?'),
mode = match[1], // @, =, or &
lastValue,
- parentGet, parentSet;
+ parentGet, parentSet, compare;
isolateScope.$$isolateBindings[scopeName] = mode + attrName;
@@ -1423,6 +1423,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
return;
}
parentGet = $parse(attrs[attrName]);
+ if (parentGet.literal) {
+ compare = equals;
+ } else {
+ compare = function(a,b) { return a === b; };
+ }
parentSet = parentGet.assign || function() {
// reset the change, or we will throw this exception on every $digest
lastValue = isolateScope[scopeName] = parentGet(scope);
@@ -1433,10 +1438,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
lastValue = isolateScope[scopeName] = parentGet(scope);
isolateScope.$watch(function parentValueWatch() {
var parentValue = parentGet(scope);
-
- if (parentValue !== isolateScope[scopeName]) {
+ if (!compare(parentValue, isolateScope[scopeName])) {
// we are out of sync and need to copy
- if (parentValue !== lastValue) {
+ if (!compare(parentValue, lastValue)) {
// parent changed and it has precedence
isolateScope[scopeName] = parentValue;
} else {
@@ -1445,7 +1449,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
}
}
return lastValue = parentValue;
- });
+ }, null, parentGet.literal);
break;
case '&':
diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js
index f2fa4ef6..853290a6 100755
--- a/test/ng/compileSpec.js
+++ b/test/ng/compileSpec.js
@@ -2492,6 +2492,62 @@ describe('$compile', function() {
expect(lastRefValueInParent).toBe('new');
}));
+
+ describe('literal objects', function() {
+ it('should copy parent changes', inject(function() {
+ compile('<div><span my-component reference="{name: name}">');
+
+ $rootScope.name = 'a';
+ $rootScope.$apply();
+ expect(componentScope.reference).toEqual({name: 'a'});
+
+ $rootScope.name = 'b';
+ $rootScope.$apply();
+ expect(componentScope.reference).toEqual({name: 'b'});
+ }));
+
+ it('should not change the component when parent does not change', inject(function() {
+ compile('<div><span my-component reference="{name: name}">');
+
+ $rootScope.name = 'a';
+ $rootScope.$apply();
+ var lastComponentValue = componentScope.reference;
+ $rootScope.$apply();
+ expect(componentScope.reference).toBe(lastComponentValue);
+ }));
+
+ it('should complain when the component changes', inject(function() {
+ compile('<div><span my-component reference="{name: name}">');
+
+ $rootScope.name = 'a';
+ $rootScope.$apply();
+ componentScope.reference = {name: 'b'};
+ expect(function() {
+ $rootScope.$apply();
+ }).toThrowMinErr("$compile", "nonassign", "Expression '{name: name}' used with directive 'myComponent' is non-assignable!");
+
+ }));
+
+ it('should work for primitive literals', inject(function() {
+ test('1', 1);
+ test('null', null);
+ test('undefined', undefined);
+ test("'someString'", 'someString');
+
+
+ function test(literalString, literalValue) {
+ compile('<div><span my-component reference="'+literalString+'">');
+
+ $rootScope.$apply();
+ expect(componentScope.reference).toBe(literalValue);
+ dealoc(element);
+
+ }
+
+ }));
+
+ });
+
});