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

Commit 146207e

Browse files
fix(ngOptions): update model if selected option is removed
Closes #7736
1 parent e92d1d9 commit 146207e

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

src/ng/directive/ngOptions.js

+11
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
335335

336336
var options;
337337
var ngOptions = parseOptionsExpression(attr.ngOptions, selectElement, scope);
338+
var previousValue;
338339

339340

340341
var renderEmptyOption = function() {
@@ -514,6 +515,7 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
514515
function updateOptions() {
515516

516517
options = ngOptions.getOptions();
518+
517519
var groupMap = {};
518520
var currentElement = selectElement[0].firstChild;
519521

@@ -586,6 +588,15 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
586588
removeExcessElements(currentElement);
587589

588590
ngModelCtrl.$render();
591+
592+
// Check to see if the value has changed due to the update to the options
593+
if(!ngModelCtrl.$isEmpty(previousValue)) {
594+
var nextValue = selectCtrl.readValue();
595+
if (!equals(previousValue, nextValue)) {
596+
ngModelCtrl.$setViewValue(nextValue);
597+
}
598+
}
599+
previousValue = selectCtrl.readValue();
589600
}
590601

591602
}

test/ng/directive/ngOptionsSpec.js

+50-2
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,17 @@ describe('ngOptions', function() {
2222
this.addMatchers({
2323
toEqualSelectValue: function(value, multiple) {
2424
var errors = [];
25+
var actual = this.actual.val();
2526

2627
if (multiple) {
2728
value = value.map(function(val) { return hashKey(val); });
29+
actual = actual || [];
2830
} else {
2931
value = hashKey(value);
3032
}
3133

32-
if (!equals(this.actual.val(), value)) {
33-
errors.push('Expected select value "' + this.actual.val() + '" to equal "' + value + '"');
34+
if (!equals(actual, value)) {
35+
errors.push('Expected select value "' + actual + '" to equal "' + value + '"');
3436
}
3537
this.message = function() {
3638
return errors.join('\n');
@@ -1279,6 +1281,52 @@ describe('ngOptions', function() {
12791281
var option = element.find('option').eq(0);
12801282
expect(option).toEqualUnknownOption();
12811283
});
1284+
1285+
1286+
it('should update the model if the selected option is removed', function() {
1287+
scope.values = [{value: 0, label: 'zero'}, {value: 1, label: 'one'}];
1288+
scope.selected = 1;
1289+
createSelect({
1290+
'ng-model': 'selected',
1291+
'ng-options': 'option.value as option.label for option in values'
1292+
});
1293+
expect(element).toEqualSelectValue(1);
1294+
1295+
scope.$apply(function() {
1296+
scope.values.pop();
1297+
});
1298+
1299+
expect(element.val()).toEqualUnknownValue();
1300+
expect(scope.selected).toEqual(null);
1301+
});
1302+
1303+
1304+
it('should update the model if all the selected (multiple) options are removed', function() {
1305+
scope.values = [{value: 0, label: 'zero'}, {value: 1, label: 'one'}, {value: 2, label: 'two'}];
1306+
scope.selected = [1, 2];
1307+
createSelect({
1308+
'ng-model': 'selected',
1309+
'multiple': true,
1310+
'ng-options': 'option.value as option.label for option in values'
1311+
});
1312+
1313+
expect(element).toEqualSelectValue([1, 2], true);
1314+
1315+
scope.$apply(function() {
1316+
scope.values.pop();
1317+
});
1318+
1319+
expect(element).toEqualSelectValue([1], true);
1320+
expect(scope.selected).toEqual([1]);
1321+
1322+
scope.$apply(function() {
1323+
scope.values.pop();
1324+
});
1325+
1326+
expect(element).toEqualSelectValue([], true);
1327+
expect(scope.selected).toEqual([]);
1328+
});
1329+
12821330
});
12831331

12841332

0 commit comments

Comments
 (0)