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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23210652/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 00:32:31  来源:igfitidea点击:

Check if object is in AngularJS array that is in localStorage

javascriptarraysangularjslocal-storage

提问by benjipelletier

I have this angularjs array: $scope.fav = []where items (objects) get added with to it on a function call. an example of these objects are {quote: "Some text", controller: some_controller}When I add a new object to the array, the array is saved in localstorage. The array works exactly how I want it to except when I try to print it in console.log() i get many [object, Object], which I just assumed is the way it is printed. This isn't the main issue though because the array works how it needs to.

我有这个 angularjs 数组:$scope.fav = []在函数调用中将项目(对象)添加到其中。这些对象的一个​​例子是{quote: "Some text", controller: some_controller}当我向数组添加一个新对象时,该数组保存在 localstorage 中。该数组完全按照我想要的方式工作,除非我尝试在 console.log() 中打印它时我得到很多 [object, Object],我只是假设它是打印的方式。不过,这不是主要问题,因为数组按其需要的方式工作。

The issue I am having is with trying to find if an object is already in an array. I have tried

我遇到的问题是尝试查找对象是否已经在数组中。我努力了

if ($scope.fav.indexOf({quote: q, controller: c}) == -1)

if ($scope.fav.indexOf({quote: q, controller: c}) == -1)

and this did not seem to work because every object going in was index -1 even if it was already in the array. I presume this is because it is not reading the object correctly.

这似乎不起作用,因为进入的每个对象的索引都是 -1,即使它已经在数组中。我认为这是因为它没有正确读取对象。

Lastly I have resorted to this function:

最后我求助于这个功能:

$scope.containsObject = function(obj, list) {
var i;
for (i = 0; i < list.length; i++) {
    if (list[i] === obj) {
        return true;
    }
}

return false;

}

}

which checks if the object is in the array. Here is how I call it:

它检查对象是否在数组中。我是这样称呼它的:

$scope.addToFav = function(q, c) {
    $scope.value = $scope.containsObject({quote: q, controller: c}, $scope.fav)
    console.log($scope.value);

}

}

I keep getting a negative value for $scope.value even if the object is in the array. Sorry for the long complicating explanation.

即使对象在数组中,我也会不断获得 $scope.value 的负值。抱歉冗长复杂的解释。

Thank you for your insight, Ben

谢谢你的洞察力,本

回答by Anthony Chu

Array.indexOf()and the ===operator compare object references and are only true when comparing references to the same instance of an object. {quote: q, controller: c}is an entirely different object instance than those in the array, even if its properties match an object in the array exactly.

Array.indexOf()===运算符比较对象引用,并且仅在比较对对象的同一实例的引用时才为真。{quote: q, controller: c}是与数组中的对象完全不同的对象实例,即使其属性与数组中的对象完全匹配。

Angular has a helper function called angular.equals()that checks of 2 objects are equivalent. You can use it in place of the ===...

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

回答by Michal Charemza

Each time you're retrieving an object from local storage, you're actually creating a new object, probably using JSON.decode, to convert the string data stored in local storage, into an object.

每次从本地存储检索对象时,实际上是在创建一个新对象,可能使用 JSON.decode 将存储在本地存储中的字符串数据转换为对象。

Even if the new object contains the same data, it will fail the strict test ===(and indeed, the loose ==) when compared to the existing (albeit apparently identical) object. indexOfuses the strict equality operator ===so this would behave the same way.

即使新对象包含相同的数据,与现有(尽管显然相同)的对象相比,它也无法通过严格的测试===(实际上是松散的==)。indexOf使用严格相等运算符,===因此这将具有相同的行为。

So you need some code to test if an object is equal to another, and then apply it to a list. One way is to use a combination of angular.equals, which performs a deep comparison of objects, and filter:

所以你需要一些代码来测试一个对象是否等于另一个对象,然后将它应用到一个列表中。一种方法是使用 的组合angular.equals,它执行对象的深度比较,和filter

$scope.containsObject = function(obj, list) {
  return list.filter(function(listItem) {
    return angular.equals(listItem, obj)
  }).length > 0;
}

The filterfunction I don't believe is part of IE8. If you need IE8 supported, you can use the polyfill, or use another library, like lo-dash

filter我不相信的功能是 IE8 的一部分。如果你需要支持 IE8,你可以使用polyfill,或者使用其他库,比如lo-dash

$scope.containsObject = function(obj, list) {
  return _.filter(list, function(listItem) {
    return angular.equals(listItem, obj)
  }).length > 0;
}