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"
在 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"