我有这个angularjs数组:$scope.fav = []
其中的项(对象)在函数调用中添加到它。这些对象的示例是{quote: "Some text", controller: some_controller}
当我向数组添加新对象时,该数组将保存在localstorage中。数组工作正是我想要的方式,除非我尝试在console.log()中打印它,我得到很多[object,Object],我只是假设它是打印的方式。这不是主要问题,因为数组工作方式如何。
我遇到的问题是尝试查找某个对象是否已存在于数组中。我试过了
if ($scope.fav.indexOf({quote: q, controller: c}) == -1)
这似乎不起作用,因为每个进入的对象都是索引-1,即使它已经在数组中。我认为这是因为它没有正确读取对象。
最后我使用了这个功能:
$scope.containsObject = function(obj, list) {
var i;
for (i = 0; i < list.length; i++) {
if (list[i] === obj) {
return true;
}
}
return false;
}
检查对象是否在数组中。我就是这样称呼的:
$scope.addToFav = function(q, c) {
$scope.value = $scope.containsObject({quote: q, controller: c}, $scope.fav)
console.log($scope.value);
}
即使对象在数组中,我仍然会为$ scope.value获取负值。 对于长期复杂的解释感到抱歉。
感谢您的见解, 本
答案 0 :(得分:7)
Array.indexOf()
和===
运算符比较对象引用,仅在比较对象的同一实例的引用时才为true。 {quote: q, controller: c}
是一个与数组中完全不同的对象实例,即使它的属性与数组中的对象完全匹配。
Angular有一个名为angular.equals()
的辅助函数,它检查2个对象是否相同。您可以使用它代替===
...
$scope.containsObject = function(obj, list) {
var i;
for (i = 0; i < list.length; i++) {
if (angular.equals(list[i], obj)) {
return true;
}
}
return false;
};
答案 1 :(得分:2)
每当您从本地存储中检索对象时,您实际上正在创建一个新对象(可能使用JSON.decode)将存储在本地存储中的字符串数据转换为对象。
即使新对象包含相同的数据,与现有(尽管看似明显相同)的对象相比,它也将无法通过严格测试===
(实际上是松散的==
)。 indexOf
使用严格相等运算符===
,因此行为方式相同。
因此,您需要一些代码来测试对象是否与另一个对象相同,然后将其应用于列表。一种方法是使用angular.equals
的组合来执行对象的深度比较,并使用filter
:
$scope.containsObject = function(obj, list) {
return list.filter(function(listItem) {
return angular.equals(listItem, obj)
}).length > 0;
}
我不相信的filter
功能是IE8的一部分。如果您需要支持IE8,可以使用polyfill,或使用其他库,例如lo-dash
$scope.containsObject = function(obj, list) {
return _.filter(list, function(listItem) {
return angular.equals(listItem, obj)
}).length > 0;
}