为什么id不能选择带有'track by'的Angular ng-options

时间:2016-10-27 10:06:22

标签: angularjs

我有一组对象,我正在使用ng-options显示,并设置带有id的ng-model。如果我在其上添加track by,则无法选择该项,如果不添加,则工作正常,为什么?以下代码:

angular.module('myApp', [])
  .controller('MyController', ['$scope', function ($scope) {
    $scope.countryList = [{id: 1, name: 'China'}, {id: 2, name: 'America'}, {id: 3, name: 'England'}]
    $scope.country = 1;
  }]);
  
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script>
<div class="container" ng-app="myApp">
  <div ng-controller="MyController">
      <p><select ng-model="country" ng-options="country.id as country.name for country in countryList"></select> no track by</p>
      <p><select ng-model="country" ng-options="country.id as country.name for country in countryList track by country.id"></select> have track by, can't selected by id</p>
  </div>
</div>

4 个答案:

答案 0 :(得分:5)

正如in this github issue - "ng-options track by and select as are not compatible"shown in this fiddle

所述

“你不能将值作为集合的标签与轨道结合起来。你必须选择其中一个。”。

对于您的情况,选择应该是:

<select ng-model="country" ng-options="country as country.name for country in countryList track by country.id"></select>

和JS

$scope.country = $scope.countryList[0];

JSFiddle here for your case

选择的值将是对象,而不仅仅是id。

同样重要的是,您必须在选择标签或逐个案例之间进行选择。

答案 1 :(得分:3)

这基本上是track by的工作方式。 track by只能使用对象而不是对象的任何属性。并且没有跟踪它将使用单独的属性而不是整个对象。检查代码部分。

来自Angular js track by的一些行(为了更好地理解,请阅读它)

  

这将有效:

 <select ng-options="item as item.label for item in items track by item.id" ng-model="selected"></select> $scope.selected = $scope.items[0];
  

但这不起作用:

<select ng-options="item.subItem as item.label for item in items track by item.id" ng-model="selected"></select> $scope.selected = $scope.items[0].subItem;

&#13;
&#13;
angular.module('myApp', [])
  .controller('MyController', ['$scope', function ($scope) {
    $scope.countryList = [{id: 1, name: 'China'}, {id: 2, name: 'America'}, {id: 3, name: 'England'}]
    $scope.country = {id: 1, name: 'China'};
   $scope.countryID = 1;
  }]);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script>
<div class="container" ng-app="myApp">
  <div ng-controller="MyController">
     
  <p><select ng-model="country" ng-options="country as country.name for country in countryList"></select> no track by</p>{{country}}
   <p><select  ng-model="country" ng-options="country as country.name for country in countryList track by country.id"></select> have track by, can't selected by id</p>{{country}}


<p><select ng-model="countryID" ng-options="country.id as country.name for country in countryList"></select> no track by</p>{{countryID}}
   <p><select  ng-model="countryID" ng-options="country.id as country.name for country in countryList track by country.id"></select> have track by, can't selected by id</p>{{countryID}}
  </div>
</div>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

根据documentation of ng-options(改写自你的例子)。

这将有效:

<select ng-model="country" ng-options="country.id as country.name for country in countryList track by country.id"></select>

$scope.country = $scope.countryList[0];

但这不起作用:

<select ng-model="country" ng-options="country.id as country.name for country in countryList track by country.id"></select>

$scope.country = $scope.countryList[0].id;

在这两个示例中,track by expression成功应用于countryList数组中的每个国家/地区。由于已在控制器中以编程方式设置所选选项,因此表达式跟踪也将应用于ngModel值。在第一个示例中,ngModel值为countryList [0],并且track by expression计算为countryList [0] .id,没有任何问题。在第二个示例中,ngModel值为countryList [0] .id,并且track by expression计算为countryList [0] .id.id(未定义)。因此,模型值与任何<option>都不匹配,<select>显示为没有选定值。

答案 3 :(得分:0)

当您在ng-model上使用track by表达式时,

ng-options行为会发生变化。

如果您使用track by,那么model的值应该是object而不是简单ID。查看 working fiddle

仅当国家/地区被指定为:

时,第二种情况才有效
$scope.country = {
  id: 3,
  name: 'England'
};