AngularJS 下拉菜单未显示所选值

AngularJS dropdown not showing selected value

在 angular 下拉列表中显示所选值时遇到问题。 当我这样给予时它有效

$scope.selectedItem = $scope.items[1];

不工作,如果我直接给出那个值

$scope.selectedItem = { name: 'two', age: 27 };

HTML:

<html ng-app="app">
  <body>
    <div ng-controller="Test">
      <select ng-model="selectedItem" ng-options="item.name for item in items">
      </select>
    </div>
  </body>
</html>

JS:

var app = angular.module('app',[]);
app.controller('Test',function($scope){
   $scope.items = [{name: 'one', age: 30 },{ name: 'two', age: 27 },{ name: 'three', age: 50 }];
  $scope.selectedItem = $scope.items[1];
});

编码: http://codepen.io/anon/pen/zxXpmR

解决方案:

谢谢samir-das。我按照你的建议修好了。

var choosen_value = { name: 'two', age: 27 };
angular.forEach($scope.items, function(item){
  if(angular.equals(choosen_value, item)){
    $scope.selectedItem = item;
  }
});

嗯,因为

$scope.items[1]{ name: 'two', age: 27 } 是完全不同的东西。

{ name: 'two', age: 27 } 是一个完全不同的对象,而 $scope.items[1] 是对象 $scope.items

的一部分

当您使用 {{}} 将某些内容放入模板时,angular 将其添加到其观察者列表中。

所以当 angular 将其放入监视列表时,它是一个不同于 $scope.items 的对象(即 { name: 'two', age: 27 } )。

selectedItem 与您在控制器中设置的对象相关联。总之,在进行脏检查时,angular 将检查 selectedItem{ name: 'two', age: 27 } 而不是 $scope.items

希望你明白我的意思

不是 Angular feature/issue,这是 Javascript 中对象相等性工作原理的结果。 This article does a fairly good job in explaining what is going on in a pretty concise way and gives some examples. Check out the source of lodash's isEqual method(它最终会带你到 baseIsEqualDeep 的定义)看看你想要实现的目标是如何在纯 JS 中完成的。

无论如何,我认为在 Angular 中没有一种简单的方法可以实现这一点,您将不得不重写 ng-options 的工作方式,您可能不想这样做去那里...

在angular中,数组和对象通过引用传递,而字符串、数字和布尔值通过值传递。因此,angular 将 $scope.items[1]{ name: 'two', age: 27 } 解释为两个不同的对象。这就是当您直接执行 $scope.selectedItem = { name: 'two', age: 27 }; 并在“$scope.items”中找到它时绑定失败的原因。

如其他答案中所述,虽然这两个对象可能具有相同的属性和值,但它们是两个不同的对象,因此 angular 认为它们不相等。

然而,您可以在 ng-options 中使用 track by 表达式来指定一个 属性 来决定是否相等:

ng-options="item.name for item in items track by item.name"

http://codepen.io/anon/pen/WbWMrp