简体   繁体   中英

Bind ng-options in ng-model on loading (like a bidirectional binding)

The situation:

I have the following select:

<select ng-model="model" ng-options="o as o.name for o in options track by o.code">
    <option value="">- Default -</option>
</select>

My options datas are like this:

$scope.options = [{id: 1, code: 'foo', name: 'Foo!'}, {id: 2, code: 'bar', name: 'Bar!'}];

What I want to do:

I want to have my select with a pre-selected value. My constraint is that I only know the code attribute of my object. With the help of the track by notation I can do that simply like this:

$scope.model = {code: 'bar'};

And it works, the selected value of the select is "Bar!"

The problem:

When I send this data to my backend, I need to send the id attribute of my object. The data sent is {code: 'bar'} but not {id: 2, code: 'bar', name: 'Bar!'} as I want.

For me it is the normal behavior... because I stored in my model {code: 'bar'} and I did not change the value selected.

The conclusion:

Is there a way to tell to AngularJS to copy the value from the options list to model when there is a default value in model (when there is a match using the track by notation) ?

Info: I know that I can do something like this $scope.model = $scope.options[2] (with some logic to determine the index...) but I would like something more magical... If it is possible... :D

OP Info : I know that I can do something like this $scope.model = $scope.options[2] (with some logic to determine the index...) but I would like something more magical... If it is possible... :D


I have 3 magic's for your 3 objects

Magic 1 :

$scope.model = $scope.options.filter(function(item) {
  return item.code=== 'bar';
})[0];

Magic 2:

app.filter('getById', function() {
  return function(input, id) {
    var i=0, len=input.length;
    for (; i<len; i++) {
      if (+input[i].id == +id) {
        return input[i];
      }
    }
    return null;
  }
});

$scope.model  = $filter('getById')($scope.options, 2);

Magic 3

angular.forEach($scope.options, function(option) {
        $scope.model = option.name == "name";
        if($scope.model !=null){break}
    });

You need to add a ng-change on the <select> and then create a function that will look for the selected option and its corresponding JSON model. Use this

HTML

<div ng-app='app' ng-controller='mainCtrl'>
    <select ng-model="model" ng-options="o as o.name for o in options track by o.code" 
    ng-change='getValue(this)'>
    <option value="">- Default -</option>
</select>
</div>

CONTROLLER

angular.module('app',['QuickList']).controller('mainCtrl', function($scope){
   $scope.options = [{id: 1, code: 'foo', name: 'Foo!'}, {id: 2, code: 'bar', name: 'Bar!'}];
   $scope.model = {code: 'bar'};
   $scope.getValue = function(item){
      console.log($scope.selectedOption = item.model);
   }
});

Whenever you will select the option in the <select> box you will see the actual JSON object for that option printed in the console.

Here is the working JSFIDDLE

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