【问题标题】:Angularjs select does not mark matching model as selectedAngularjs select不会将匹配模型标记为选中
【发布时间】:2014-09-07 01:28:08
【问题描述】:

我的 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];

}

【问题讨论】:

    标签: javascript angularjs angularjs-ng-options angularjs-ng-model


    【解决方案1】:

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

    您也可以使用track by 通过state.id 代替对象的$hashKey 进行Angular 跟踪:

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

    【讨论】:

      【解决方案2】:

      如果你提供一个对象作为模型,它不包含对现有列表的引用,那么使用 track by 和你的模型的唯一值,这样就可以代替使用自定义的唯一 $$hashKey,ng- options 将使用您在 track by 中提供的属性来跟踪正在设置的 ng-model。

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

      Demo

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

      这是very good example for this

      【讨论】:

        【解决方案3】:

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

        注意: 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];
        

        【讨论】:

        • 根据 ng-option 的工作方式,这并不完全正确,您始终可以通过某些东西进行跟踪并设置模型具有该属性值。其他方法是使用value as name for item in .. 语法。您不能总是知道所选项目在数组中属于哪个索引(除非您循环获取效率很低的匹配项)
        • @PSL 这是基于 Angular 团队的文档,如果它不完整 Angular 团队也犯了同样的错误。
        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

          尝试添加 在 ng-options 语句末尾按 state.id 跟踪。

          【讨论】:

            【解决方案6】:

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-11-23
              • 1970-01-01
              • 1970-01-01
              • 2017-02-06
              • 1970-01-01
              • 1970-01-01
              • 2016-07-17
              • 2020-04-05
              相关资源
              最近更新 更多