在ng-options删除所选选项之后,如何使ng-model与select元素保持同步

时间:2021-04-21 20:15:40

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时,我找不到反向检查。