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

Commit 7e5c447

Browse files
Narretzpetebacondarwin
authored andcommitted
fix(select): don't call $render twice if $viewValue ref changes
Credits to @tepez for the fix Closes #11329 Closes #11412
1 parent 4ba43d2 commit 7e5c447

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

src/ng/directive/select.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,6 @@ var SelectController =
141141
*
142142
*/
143143
var selectDirective = function() {
144-
var lastView;
145144

146145
return {
147146
restrict: 'E',
@@ -200,11 +199,13 @@ var selectDirective = function() {
200199

201200
// we have to do it on each watch since ngModel watches reference, but
202201
// we need to work of an array, so we need to see if anything was inserted/removed
202+
var lastView, lastViewRef = NaN;
203203
scope.$watch(function selectMultipleWatch() {
204-
if (!equals(lastView, ngModelCtrl.$viewValue)) {
204+
if (lastViewRef === ngModelCtrl.$viewValue && !equals(lastView, ngModelCtrl.$viewValue)) {
205205
lastView = shallowCopy(ngModelCtrl.$viewValue);
206206
ngModelCtrl.$render();
207207
}
208+
lastViewRef = ngModelCtrl.$viewValue;
208209
});
209210

210211
// If we are a multiple select then value is now a collection

test/ng/directive/selectSpec.js

+54
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,60 @@ describe('select', function() {
841841
expect(element).toBeDirty();
842842
});
843843

844+
845+
describe('calls to $render', function() {
846+
847+
var ngModelCtrl;
848+
849+
beforeEach(function() {
850+
compile(
851+
'<select name="select" ng-model="selection" multiple>' +
852+
'<option>A</option>' +
853+
'<option>B</option>' +
854+
'</select>');
855+
856+
ngModelCtrl = element.controller('ngModel');
857+
spyOn(ngModelCtrl, '$render').andCallThrough();
858+
});
859+
860+
861+
it('should call $render once when the reference to the viewValue changes', function() {
862+
scope.$apply(function() {
863+
scope.selection = ['A'];
864+
});
865+
expect(ngModelCtrl.$render.calls.length).toBe(1);
866+
867+
scope.$apply(function() {
868+
scope.selection = ['A', 'B'];
869+
});
870+
expect(ngModelCtrl.$render.calls.length).toBe(2);
871+
872+
scope.$apply(function() {
873+
scope.selection = [];
874+
});
875+
expect(ngModelCtrl.$render.calls.length).toBe(3);
876+
});
877+
878+
879+
it('should call $render once when the viewValue deep-changes', function() {
880+
scope.$apply(function() {
881+
scope.selection = ['A'];
882+
});
883+
expect(ngModelCtrl.$render.calls.length).toBe(1);
884+
885+
scope.$apply(function() {
886+
scope.selection.push('B');
887+
});
888+
expect(ngModelCtrl.$render.calls.length).toBe(2);
889+
890+
scope.$apply(function() {
891+
scope.selection.length = 0;
892+
});
893+
expect(ngModelCtrl.$render.calls.length).toBe(3);
894+
});
895+
896+
});
897+
844898
});
845899

846900

0 commit comments

Comments
 (0)