21

我的 ngModel 在选择时遇到问题,未显示为已选择。id 和 name 都匹配,但它不起作用,请参阅 selectedState。将模型指向选项数组中的实际对象有效,请参阅 selectedState2。不知道发生了什么...

小提琴:http: //jsfiddle.net/fedorsmirnoff/b49n4Ldp/2/

<select ng-model="selectedState" ng-options="state.name for state in stateOptions"></select>

<select ng-model="selectedState2" ng-options="state.name for state in stateOptions"></select>

function MainCtrl($scope) {
 $scope.stateOptions = [
     {id: 1, name: "Alaska"},
     {id: 2, name: "Montana"},
     {id: 3, name: "Nebraska"},
     {id: 4, name: "Texas"}
  ]

 $scope.selectedState = {id: 2, name: "Montana"};

 $scope.selectedState2 = $scope.stateOptions[1];

}
4

6 回答 6

32

这是因为每个对象都有自己$hashKey的 Angular 提供的,Angular 使用它来确定它们是否相同。您正在创建一个新对象(具有不同的$hashKey$scope.selectedState。您设置它的方式$scope.selectedState2是正确的。

您还可以使用track bystate.id代替对象的Angular 跟踪$hashKey

<select ng-model="selectedState" ng-options="state.name for state in stateOptions track by state.id"></select>
于 2014-09-07T01:34:24.177 回答
8

如果您提供一个对象作为不包含对现有列表的引用的模型,则使用track by您的模型的唯一值,以便 ng-options 不使用自定义唯一 $$hashKey,而是使用该属性您在 track by 中提供用于跟踪正在设置的 ng-model。

  ng-options="state.name for state in stateOptions track by state.id"

演示

它不仅在将 ng-model 设置为任何引用时很有用,而且它还具有很大的性能效率,尤其是当您的列表被刷新时,元素不会被删除和重新创建,而是 angular 只会更新现有的元素。

这是一个很好的例子

于 2014-09-07T01:38:03.907 回答
3

Angular 团队在 ngSelect 的文档中说明了这个问题

注意: ngModel 通过引用而不是值进行比较。这在绑定到对象数组时很重要。请参阅此jsfiddle中的示例。

 $scope.options = [
    { label: 'one', value: 1 },
    { label: 'two', value: 2 }
  ];

  // Although this object has the same properties as the one in $scope.options,
  // Angular considers them different because it compares based on reference
  $scope.incorrectlySelected = { label: 'two', value: 2 };

  // Here we are referencing the same object, so Angular inits the select box correctly
  $scope.correctlySelected = $scope.options[1];
于 2014-09-07T01:36:13.333 回答
2

当您设置 $scope.selectedState 时,您实际上是在创建一个新的 javascript 对象,它不是 $scope.stateOptions 的元素。因此,选择元素不会从 $scope.stateOptions 中选择相应的元素。

如果您需要通过唯一的 attr 值选择项目,您可以在选择表达式中使用“track by”。

于 2014-09-07T01:34:34.617 回答
1

尝试在 ng-options 语句的末尾添加 Track by state.id。

于 2014-09-07T01:35:38.627 回答
0

我认为 Angular 使用引用检查而不是比较具有相同属性的两个对象。在您的情况下 $scope.selectedState2 返回一个不同的对象。我通常使用 understore 从数组中查找所选项目进行初始化。

于 2014-09-07T01:42:38.813 回答