2

Simple problem, probably discussed many times, but I can't find a proper solution on this simple issue.

The problem:
modifications on selected items have no effect on the view (which it should).

Controller:

var myApp = angular.module('myApp', ['ui.select2']);

function MyCtrl($scope) {
    $scope.selectedDaltons = [4]; // Averell is preselected (id:4)
    $scope.daltons = [
        { id: 1, name: 'Joe' },
        { id: 2, name: 'William' },
        { id: 3, name: 'Jack' },
        { id: 4, name: 'Averell' },
        { id: 5, name: 'Ma' }
    ];
    $scope.changeAverellsName = function() {
        // Fiddle's issue!! 
        // observe, that the selected item on the view does not change!!
        $scope.daltons[3].name = "Idiot";
    };
};

View:

<div ng-controller="MyCtrl">

    <!-- changing model via click -->
    <button ng-click="changeAverellsName()">change Averell's name to 'Idiot'</button>

    <!-- selected items are not binded to the model -->
    <select multiple ui-select2 class="form-control" id="70.1.6.3" data-ng-model="selectedDaltons">
        <option data-ng-repeat="dalton in daltons" value="{{dalton.id}}" text="">{{dalton.name}}</option>
    </select>

    <!-- this list is for assure, that two way binding works -->
    <ul>
        <li data-ng-repeat="dalton in daltons">{{dalton.name}}</li>
    </ul>
</div>


Here as jsfiddle


How can I make the two way binding work?

4

1 回答 1

3

从第 134 行的源代码,源集合被监视,它只监视集合的变化(删除或添加项目),而不是项目属性的值发生变化。要同时观察项目属性的变化,手表需要编码为:

scope.$watch(watch, function (newVal, oldVal, scope) { 
  if (angular.equals(newVal, oldVal)) { 
    return; 
  } 
  // Delayed so that the options have time to be rendered 
  $timeout(function () { 
    elm.select2('val', controller.$viewValue); 
    // Refresh angular to remove the superfluous option 
    controller.$render(); 
    if(newVal && !oldVal && controller.$setPristine) { 
      controller.$setPristine(true); 
    } 
  }); 
}, true); 

注意 watch 函数末尾的“true”。为了解决这个问题,您需要使用 map 将源集合复制回自身。

于 2014-09-02T15:05:22.170 回答