简体   繁体   中英

How can I keep ng-model in sync with a select element after ng-options removes the selected option

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?

<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.

Thanks for your feedback.

Update: I fixed a typo where referred to ng-options as ng-select.

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

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.

then what u need to do is change model value manually as $scope.foo = null;

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.

angular.js

line 21371:

self.databound = $attrs.ngModel;

line 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM