简体   繁体   中英

ng-model not binding on ng-repeated options in select element

Somehow I seem to achieved only one way data binding when using an ng-model inside an ng-repeat.

Currently if the user makes a selection from one of the dropdowns, the model is updated. But for some reason the selects are not binding to changes in the model.

<body ng-controller="MainCtrl as c">
  <table>
      <tr ng-repeat="controller in c.data">
        <td>
          <select ng-model="controller.port" required="" class="form-control form-control-inline">
            <option value="">Choose a port</option>
            <option value="{{idx}}" ng-repeat="idx in c.pwm" ng-disabled="c.isPWMUsed(idx)">
              {{idx}} {{c.isPWMUsed(idx)? 'used' : ''}}
            </option>
          </select>
        </td>
      </tr>
  </table>
  <pre>
{{c.data | json:4}}
  </pre>
</body>

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
    this.data = [
        {
            "port": 1
        },
        {
            "port": "2"
        },
        {
            "port": ""
        },
        {
            "port": "5"
        }
    ];
    this.pwm = [0,1,2,3,4,5,6,7,8,9];

    this.isPWMUsed = function (n) {
        var out = false;
        n=n.toString();
        for (var i = 0; i < this.data.length; i++) {
            if (this.data[i].port === n) {
                out = true;
                break;
            }
        }
        return out;
    };

    $scope.gettypeof = function(item){
        return (typeof item);
    };
});

Here is a plunker: http://plnkr.co/edit/QlEP73aZwhjcjRGszbJb?p=preview Notice how the default data has some ports preassigned. However they do not seem to be bound to the dropdowns properly.

-- Edit --
The reason I did not use ng-options was because I could not figure out how to disable options when they are selected. Notice the functionality adding ng-disabled="c.isPWMUsed(idx)" adds, making it so that the user cannot select an item that has been selected with one of the other dropdowns.

-- Edit 2 --
So really the question boils down to "is there a way to make two way binding work for select when options come from ng-repeat?"

Another Identical Case, Using the code from the AngularJS docs on select

if I change this bit of markup

<select ng-model="myColor" ng-options="color.name for color in colors">
  <option value="">-- choose color --</option>
</select>

To this bit of markup

<select ng-model="myColor">
  <option value="">-- choose color --</option>
  <option value="{{idx}}" ng-repeat="(idx, color) in colors">{{color.name}}</option>
</select>

The data binding on the middle select stops working. Is there a way to make the data binding work using the ng-repeat and not ng-options?

-- Edit 3 --
This code seems to work...

 var myApp = angular.module('myApp', []); myApp.controller('AppCtrl', ['$scope', function AppCtrl($scope) { $scope.filterCondition = { operator: 'eq' } $scope.operators = [{ value: 'eq', displayName: 'equals', title: 'The equals operator does blah, blah' }, { value: 'neq', displayName: 'not equal', title: 'The not equals operator does yada yada' }] }]); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.js"></script> <body ng-app="myApp" ng-controller="AppCtrl"> <div>Operator is: {{filterCondition.operator}}</div> <select ng-model="filterCondition.operator"> <option ng-repeat="operator in operators" title="{{operator.title}}" ng-selected="{{operator.value == filterCondition.operator}}" value="{{operator.value}}">{{operator.displayName}}</option> </select> <select ng-model="filterCondition.operator"> <option ng-repeat="operator in operators" title="{{operator.title}}" ng-selected="{{operator.value == filterCondition.operator}}" value="{{operator.value}}">{{operator.displayName}}</option> </select> <input ng-model="filterCondition.operator"> </body> 

Forked your plnkr

<select ng-model="controller.port" required="" class="form-control form-control-inline"  ng-options="item as (item + (c.isPWMUsed(item)?'used' : '')) for item in c.pwm">
                    <option value="">Choose a port</option>
                </select>
  • I have used ng-value instead of value. Somehow value is not working

  • Initial string value in also not working. If you set initial value as string, it is not working. (Don't know why?)

  • If you want to use ng-option, then you will not have ng-disabled. But ng-option gives you better support than repeat on option. There are some third party directive which you can use to disable option in ng-option also. Checkout this . This is an example to disabled option working with ng-option.

@dhavalcengg had one solution however it didn't allow for disabling selected options.

As it turns out I just had to add an ng-selected attribute to the option to force it to select when the predefined value was already set.

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