Angular UI Select2, why does ng-model get set as J

2019-04-23 04:26发布

问题:

I'm using angular-ui's select2 for a fairly simple dropdown. It's backed by a static array of data sitting on my controller's scope. In my controller I have a function that gets called on ng-change of the dropdown so that I can perform some actions when the value changes.

However, what I'm finding is that the ng-model's property gets set as a JSON string rather than an actual javascript object, which makes it impossible to use dot notation to grab properties off of that model.

Here's the function that handles the value of the dropdown getting changed:

$scope.roleTypeChanged = function() {
  //fine:
  console.log('selectedType is: ', $scope.adminModel.selectedType);

  // this ends up being undefined because $scope.adminModel.selectedType is a 
  // JSON string, rather than a js object:
  console.log('selectedType.typeCode is: ', $scope.adminModel.selectedType.typeCode);
}

Here's a plunker of my full example: http://plnkr.co/edit/G39iZC4f7QH05VctY8zG

I've never seen a property that's bound to ng-model do this before, however I'm also fairly new to Angular so it's likely that I'm just doing something wrong here. I can certainly do something like $.parseJSON() to convert the JSON string back to an object, but I'd rather not unless I have to. Thanks for any help!

回答1:

You need to use ng-options on your select if you want to have object values. Actually creating the options yourself using an ng-repeat will only allow you to have string values for the various options:

<select ui-select2
    ng-model="adminModel.selectedType"
    ng-change="roleTypeChanged()"
    data-placeholder="Select Role Type" ng-options="type.displayName for type in adminModel.roleTypes">
  <option value=""></option>
</select>

http://plnkr.co/edit/UydBai3Iy9GQg6KphhN5?p=preview



回答2:

Thanks Karl! I have struggled a day with this

as a note for others having similar problems as I did, when using an ng-model not accessible and defined in the controller/directive I solved it like this.

//country.Model has Code and Name nodes

* HTML *

 <select 
name="country" data-ng-model="country.Model"  
    data-ui-select2=""  
    data-ng-change="countryChanged(country.Model)"  <!--only for test, log to console-->
    data-ng-options="country as CodeAndName(country) for country in countries"
    data-placeholder="{{placeholderText(country.Model, '- - Select Country - -')}}" >
    <option value=""></option>
</select>  

* JS *

 function controller($scope, $q, $location, $routeParams) {

    $scope.countryChanged = function(item) { // for test                
      console.log('selectedType is: ', item);
    };

    //returns the item or the text if no item is selected
    $scope.placeholderText = function (item, text){ 
        if (item == undefined)
            return text;
        return $scope.CodeAndName(item);
    };

    // returns a string for code and name of the item, used to set the placeholder text
    $scope.CodeAndName = function (item) { 
        if (item == undefined)
            return '';
        return item.Code + ' - ' + item.Name;
    };