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

Commit c175619

Browse files
committed
fix($parse): allow watching array/object literal values
- the content of array/object literals is now watched for changes - if the content changes then a new array/object will be constructed
1 parent 828f8a6 commit c175619

File tree

2 files changed

+72
-4
lines changed

2 files changed

+72
-4
lines changed

src/ng/parse.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -1786,13 +1786,13 @@ function $ParseProvider() {
17861786
}
17871787
}
17881788

1789-
function expressionInputDirtyCheck(newValue, oldValueOfValue) {
1789+
function expressionInputDirtyCheck(newValue, oldValueOfValue, compareObjectIdentity) {
17901790

17911791
if (newValue == null || oldValueOfValue == null) { // null/undefined
17921792
return newValue === oldValueOfValue;
17931793
}
17941794

1795-
if (typeof newValue === 'object') {
1795+
if (typeof newValue === 'object' && !compareObjectIdentity) {
17961796

17971797
// attempt to convert the value to a primitive type
17981798
// TODO(docs): add a note to docs that by implementing valueOf even objects and arrays can
@@ -1821,7 +1821,7 @@ function $ParseProvider() {
18211821
inputExpressions = inputExpressions[0];
18221822
return scope.$watch(function expressionInputWatch(scope) {
18231823
var newInputValue = inputExpressions(scope);
1824-
if (!expressionInputDirtyCheck(newInputValue, oldInputValueOf)) {
1824+
if (!expressionInputDirtyCheck(newInputValue, oldInputValueOf, parsedExpression.literal)) {
18251825
lastResult = parsedExpression(scope, undefined, undefined, [newInputValue]);
18261826
oldInputValueOf = newInputValue && getValueOf(newInputValue);
18271827
}
@@ -1841,7 +1841,7 @@ function $ParseProvider() {
18411841

18421842
for (var i = 0, ii = inputExpressions.length; i < ii; i++) {
18431843
var newInputValue = inputExpressions[i](scope);
1844-
if (changed || (changed = !expressionInputDirtyCheck(newInputValue, oldInputValueOfValues[i]))) {
1844+
if (changed || (changed = !expressionInputDirtyCheck(newInputValue, oldInputValueOfValues[i], parsedExpression.literal))) {
18451845
oldInputValues[i] = newInputValue;
18461846
oldInputValueOfValues[i] = newInputValue && getValueOf(newInputValue);
18471847
}

test/ng/parseSpec.js

+68
Original file line numberDiff line numberDiff line change
@@ -3117,6 +3117,74 @@ describe('parser', function() {
31173117
scope.$digest();
31183118
expect(objB.value).toBe(scope.input);
31193119
}));
3120+
3121+
it('should support watching literals', inject(function($parse) {
3122+
var lastVal = NaN;
3123+
var callCount = 0;
3124+
var listener = function(val) { callCount++; lastVal = val; };
3125+
3126+
scope.$watch('{val: val}', listener);
3127+
3128+
scope.$apply('val = 1');
3129+
expect(callCount).toBe(1);
3130+
expect(lastVal).toEqual({val: 1});
3131+
3132+
scope.$apply('val = []');
3133+
expect(callCount).toBe(2);
3134+
expect(lastVal).toEqual({val: []});
3135+
3136+
scope.$apply('val = []');
3137+
expect(callCount).toBe(3);
3138+
expect(lastVal).toEqual({val: []});
3139+
3140+
scope.$apply('val = {}');
3141+
expect(callCount).toBe(4);
3142+
expect(lastVal).toEqual({val: {}});
3143+
}));
3144+
3145+
it('should only watch the direct inputs to literals', inject(function($parse) {
3146+
var lastVal = NaN;
3147+
var callCount = 0;
3148+
var listener = function(val) { callCount++; lastVal = val; };
3149+
3150+
scope.$watch('{val: val}', listener);
3151+
3152+
scope.$apply('val = 1');
3153+
expect(callCount).toBe(1);
3154+
expect(lastVal).toEqual({val: 1});
3155+
3156+
scope.$apply('val = [2]');
3157+
expect(callCount).toBe(2);
3158+
expect(lastVal).toEqual({val: [2]});
3159+
3160+
scope.$apply('val.push(3)');
3161+
expect(callCount).toBe(2);
3162+
3163+
scope.$apply('val.length = 0');
3164+
expect(callCount).toBe(2);
3165+
}));
3166+
3167+
it('should only watch the direct inputs to nested literals', inject(function($parse) {
3168+
var lastVal = NaN;
3169+
var callCount = 0;
3170+
var listener = function(val) { callCount++; lastVal = val; };
3171+
3172+
scope.$watch('[{val: [val]}]', listener);
3173+
3174+
scope.$apply('val = 1');
3175+
expect(callCount).toBe(1);
3176+
expect(lastVal).toEqual([{val: [1]}]);
3177+
3178+
scope.$apply('val = [2]');
3179+
expect(callCount).toBe(2);
3180+
expect(lastVal).toEqual([{val: [[2]]}]);
3181+
3182+
scope.$apply('val.push(3)');
3183+
expect(callCount).toBe(2);
3184+
3185+
scope.$apply('val.length = 0');
3186+
expect(callCount).toBe(2);
3187+
}));
31203188
});
31213189

31223190
describe('locals', function() {

0 commit comments

Comments
 (0)