检查对象是否在localStorage中的AngularJS数组中

时间:2014-04-22 04:54:06

标签: javascript arrays angularjs local-storage

我有这个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获取负值。 对于长期复杂的解释感到抱歉。

感谢您的见解, 本

2 个答案:

答案 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;
}