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

Commit 34a6da2

Browse files
fix(ngOptions): do not watch properties starting with $
Expressions that compute labels and track by values for ngOptions were being called for properties, that start with $ even though those properties were being ignored as options. Closes #11930 Closes #12010
1 parent ebaa0f5 commit 34a6da2

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

src/ng/directive/ngOptions.js

+1
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
303303
values = values || [];
304304

305305
Object.keys(values).forEach(function getWatchable(key) {
306+
if (key.charAt(0) === '$') return;
306307
var locals = getLocals(values[key], key);
307308
var selectValue = getTrackByValueFn(values[key], locals);
308309
watchedArray.push(selectValue);

test/ng/directive/ngOptionsSpec.js

+35
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,41 @@ describe('ngOptions', function() {
448448
});
449449

450450

451+
it('should not watch array properties that start with $ or $$', function() {
452+
createSelect({
453+
'ng-options': 'value as createLabel(value) for value in array',
454+
'ng-model': 'selected'
455+
});
456+
scope.createLabel = jasmine.createSpy('createLabel').andCallFake(function(value) { return value; });
457+
scope.array = ['a', 'b', 'c'];
458+
scope.array.$$private = 'do not watch';
459+
scope.array.$property = 'do not watch';
460+
scope.selected = 'b';
461+
scope.$digest();
462+
463+
expect(scope.createLabel).toHaveBeenCalledWith('a');
464+
expect(scope.createLabel).toHaveBeenCalledWith('b');
465+
expect(scope.createLabel).toHaveBeenCalledWith('c');
466+
expect(scope.createLabel).not.toHaveBeenCalledWith('do not watch');
467+
});
468+
469+
470+
it('should not watch object properties that start with $ or $$', function() {
471+
createSelect({
472+
'ng-options': 'key as createLabel(key) for (key, value) in object',
473+
'ng-model': 'selected'
474+
});
475+
scope.createLabel = jasmine.createSpy('createLabel').andCallFake(function(value) { return value; });
476+
scope.object = {'regularProperty': 'visible', '$$private': 'invisible', '$property': 'invisible'};
477+
scope.selected = 'regularProperty';
478+
scope.$digest();
479+
480+
expect(scope.createLabel).toHaveBeenCalledWith('regularProperty');
481+
expect(scope.createLabel).not.toHaveBeenCalledWith('$$private');
482+
expect(scope.createLabel).not.toHaveBeenCalledWith('$property');
483+
});
484+
485+
451486
it('should allow expressions over multiple lines', function() {
452487
scope.isNotFoo = function(item) {
453488
return item.name !== 'Foo';

0 commit comments

Comments
 (0)