Skip to content

Commit 13589d1

Browse files
author
Steven Easter
committed
fix(ngOptions): use reference check only when not using trackBy
Change the check on changed value for ngOptions to ensure that a reference check is only done when trackBy is not used. Previously, if trackBy was being used but the values of the objects were equal a reference check was then used which would cause the check to be true if the objects had different memory references but the values were equal. This can cause issues with forms being marked dirty when the value of the model as not actually changed. Closes angular#11936
1 parent 291d7c4 commit 13589d1

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

src/ng/directive/ngOptions.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,7 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
707707
if (!ngModelCtrl.$isEmpty(previousValue)) {
708708
var nextValue = selectCtrl.readValue();
709709
if (ngOptions.trackBy && !equals(previousValue, nextValue) ||
710-
previousValue !== nextValue) {
710+
!ngOptions.trackBy && previousValue !== nextValue) {
711711
ngModelCtrl.$setViewValue(nextValue);
712712
ngModelCtrl.$render();
713713
}

test/ng/directive/ngOptionsSpec.js

+22
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,28 @@ describe('ngOptions', function() {
11761176

11771177
});
11781178

1179+
it('should not set view value again if the tracked property of the model has not changed when using trackBy', function() {
1180+
1181+
createSelect({
1182+
'ng-model': 'selected',
1183+
'ng-options': 'item for item in arr track by item.id'
1184+
});
1185+
1186+
scope.$apply(function() {
1187+
scope.selected = {id: 10, label: 'ten'};
1188+
});
1189+
1190+
spyOn(element.controller('ngModel'), '$setViewValue');
1191+
1192+
scope.$apply(function() {
1193+
scope.arr[0] = {id: 10, label: 'ten'};
1194+
});
1195+
1196+
// update render due to equality watch
1197+
expect(element.controller('ngModel').$setViewValue).not.toHaveBeenCalled();
1198+
1199+
});
1200+
11791201
it('should not re-render if a property of the model is changed when not using trackBy', function() {
11801202

11811203
createSelect({

0 commit comments

Comments
 (0)