I have a select element with an ng-model and ng-options on it. ng-options makes the possible selections dynamic however I have noticed that when ng-options updates the options ng-model is not also getting updated. For example if the select element has the value of "foo" selected then the ng-options model is updated and "foo" is no longer an option the selector updates to blank but ng-model still shows "foo" as its value. I would expect that ng-model would update as well to equal null. The only thing I can think of is to add a watch on items but that seems kind of lame. What is the best way to get ng-model to stay in sync with the select element in this scenario?
我有一个带有ng模型和ng选项的select元素。ng-options使可能的选择是动态的,但是我注意到,当ng-options更新时,ng-model也没有得到更新。例如,如果select元素的值为“foo”,那么ng-options模型将被更新,而“foo”不再是选择器更新为blank的选项,但ng-model仍然显示“foo”作为它的值。我希望ng-model也能更新为null。我能想到的唯一一件事就是在物品上加一块手表,但这似乎有点蹩脚。在这个场景中,让ng-model与select元素保持同步的最佳方式是什么?
<div ng-controller="MyCtrl">
<p>Selected Item: {{foo}}</p>
<p>
<label>option</label>
<select ng-model="foo" ng-options="item.val as item.label for item in items">
<option value="">Select Something</option>
</select>
</p>
<button ng-click="remove()">Remove Second Item Option</button>
<p>{{items}}</p>
</div>
Here is the jsfiddle to illustrate the issue. http://jsfiddle.net/dberringer/m2rm8Lh6/2/ Note: I'm aware I could manually update the foo value with the delete method. This method is just to illustrate the issue.
下面是用来说明这个问题的jsfiddle。http://jsfiddle.net/dberringer/m2rm8Lh6/2/ Note:我知道我可以用delete方法手动更新foo值。这种方法只是为了说明问题。
Thanks for your feedback.
谢谢你的反馈。
Update: I fixed a typo where referred to ng-options as ng-select.
更新:我修正了一个错误,其中提到了ng-select选项。
2 个解决方案
#1
2
change the button like
改变按钮等
<button ng-click="remove(2)">Remove Second Item Option</button>
change the remove function
修改删除功能
$scope.remove = function(removeIndex) {
if($scope.foo == removeIndex) {
$scope.foo = null;
}
$scope.items.splice(removeIndex-1,1);
};
here is the Demo Fiddle
这是演示小提琴
Reason is,
原因是,
ng-change
is not going to trigger when,
当,
if the model is changed programmatically and not by a change to the input value, check the Doc here
如果模型是通过编程方式改变的,而不是通过对输入值的更改,那么检查这里的Doc。
so u are not changing the select value by changing the select box instead do it using a button (programmatically) so angular will not trigger the change event on the select element and then angular doesn't know model is changed ,this might be the reason.
所以u并没有通过改变选择框来改变选择值而是通过一个按钮(程序化地)来改变它,所以角不会触发select元素上的改变事件然后角不知道模型被改变了,这可能是原因。
then what u need to do is change model value manually as
$scope.foo = null;
然后,您需要做的是将模型值手工更改为$scope。foo =零;
#2
1
I think angular didn't check that, once the ngOptions value changes, angular didn't do a check to see if the ngModel is exists in ngOptions.
我认为角没有检查,一旦ngOptions的值改变,角没有检查ngModel是否存在于ngOptions中。
angular.js
angular.js
line 21371:
21371行:
self.databound = $attrs.ngModel;
line 21828 - 21840:
21828 - 21840行:
return function (scope, element, attr) {
var selectCtrlName = '$selectController',
parent = element.parent(),
selectCtrl = parent.data(selectCtrlName) ||
parent.parent().data(selectCtrlName); // in case we are in optgroup
if (selectCtrl && selectCtrl.databound) {
// For some reason Opera defaults to true and if not overridden this messes up the repeater.
// We don't want the view to drive the initialization of the model anyway.
element.prop('selected', false);
} else {
selectCtrl = nullSelectCtrl;
}
You can see above code checks which option should be selected when generated the options, but i can't find a reverse check when ngOptions got updated.
您可以看到上面的代码检查在生成选项时应该选择哪个选项,但是当更新ngOptions时,我找不到反向检查。
#1
2
change the button like
改变按钮等
<button ng-click="remove(2)">Remove Second Item Option</button>
change the remove function
修改删除功能
$scope.remove = function(removeIndex) {
if($scope.foo == removeIndex) {
$scope.foo = null;
}
$scope.items.splice(removeIndex-1,1);
};
here is the Demo Fiddle
这是演示小提琴
Reason is,
原因是,
ng-change
is not going to trigger when,
当,
if the model is changed programmatically and not by a change to the input value, check the Doc here
如果模型是通过编程方式改变的,而不是通过对输入值的更改,那么检查这里的Doc。
so u are not changing the select value by changing the select box instead do it using a button (programmatically) so angular will not trigger the change event on the select element and then angular doesn't know model is changed ,this might be the reason.
所以u并没有通过改变选择框来改变选择值而是通过一个按钮(程序化地)来改变它,所以角不会触发select元素上的改变事件然后角不知道模型被改变了,这可能是原因。
then what u need to do is change model value manually as
$scope.foo = null;
然后,您需要做的是将模型值手工更改为$scope。foo =零;
#2
1
I think angular didn't check that, once the ngOptions value changes, angular didn't do a check to see if the ngModel is exists in ngOptions.
我认为角没有检查,一旦ngOptions的值改变,角没有检查ngModel是否存在于ngOptions中。
angular.js
angular.js
line 21371:
21371行:
self.databound = $attrs.ngModel;
line 21828 - 21840:
21828 - 21840行:
return function (scope, element, attr) {
var selectCtrlName = '$selectController',
parent = element.parent(),
selectCtrl = parent.data(selectCtrlName) ||
parent.parent().data(selectCtrlName); // in case we are in optgroup
if (selectCtrl && selectCtrl.databound) {
// For some reason Opera defaults to true and if not overridden this messes up the repeater.
// We don't want the view to drive the initialization of the model anyway.
element.prop('selected', false);
} else {
selectCtrl = nullSelectCtrl;
}
You can see above code checks which option should be selected when generated the options, but i can't find a reverse check when ngOptions got updated.
您可以看到上面的代码检查在生成选项时应该选择哪个选项,但是当更新ngOptions时,我找不到反向检查。