Сравнить объекты в Angular

79

Можно ли в Angular провести «глубокое» сравнение двух объектов? Я хотел бы сравнить каждую пару ключ / значение. Например:

Объект 1

{
   key1: "value1",
   key2: "value2",
   key3: "value3"
}

Объект 2

{
   key1: "value1",
   key2: "newvalue",
   key3: "value3" 
}

Мне нужно, чтобы сравнение не удалось, поскольку только одна из пар ключ / значение отличается. Другими словами, ВСЕ пары ключ / значение должны точно совпадать, иначе произойдет сбой. Это что-то уже встроено в Angular. Я уверен, что мог бы написать свой собственный сервис, если бы мне действительно было нужно, но я надеялся, что он уже встроен. Подобно angular.equals.

selanac82
источник

Ответы:

205

Для сравнения двух объектов вы можете использовать:

angular.equals(obj1, obj2)

Он проводит глубокое сравнение и не зависит от порядка клавиш. См. AngularJS DOCS и небольшую демонстрацию.

var obj1 = {
  key1: "value1",
  key2: "value2",
  key3: {a: "aa", b: "bb"}
}

var obj2 = {
  key2: "value2",
  key1: "value1",
  key3: {a: "aa", b: "bb"}
}

angular.equals(obj1, obj2) //<--- would return true
Клод
источник
6
Обратите внимание, что angular.equals проверяет идентичность, а не равенство . TL; DR:angular.equals( { id: "12" }, { id: 12 } ) // is false
bobjones
@bobjones angular.equals возвращает истину на основе идентичности ИЛИ глубокого равенства, поэтому предлагаемый вами пример вернет истину. см. документацию angular.equals , в частности Два объекта или значения считаются эквивалентными, если выполняется хотя бы одно из следующих утверждений
tommyTheHitMan
5
@tommyTheHitMan: пример bobjones возвращается, falseпотому что на основе идентичности "12"===12 // is false. Просто попробуйте.
klode
А если вам нужен объект diff для отслеживания истории откатов, посмотрите это ... gist.github.com/katowulf/6193808
Марк,
4
Небольшое примечание: angular.equals () игнорирует все свойства, начинающиеся с $, и все свойства, значения которых являются функциями, если оба аргумента являются объектами.
im1dermike
24

Предполагая, что порядок в обоих объектах одинаковый, просто stringifyих обоих и сравните!

JSON.stringify(obj1) == JSON.stringify(obj2);
tymeJV
источник
14
angular.equals (obj1, obj2) также должен работать. Это не зависит от порядка ключей и является глубоким (это называется рекурсивно) code.angularjs.org/1.2.0/docs/api/angular.equals
klode 05
4
Это было бы очень плохим предположением!
голографический принцип
1
angular.toJsonтакже удалил бы $$ hashKeys
5

Немного поздно на этой теме. angular.equals выполняет глубокую проверку, однако кто-нибудь знает, почему он ведет себя по-другому, если один из членов содержит префикс «$»?

Вы можете попробовать эту демонстрацию со следующим вводом

var obj3 = {}
obj3.a=  "b";
obj3.b={};
obj3.b.$c =true;

var obj4 = {}
obj4.a=  "b";
obj4.b={};
obj4.b.$c =true;

angular.equals(obj3,obj4);
КМ.
источник
4
Из документации Angular: «Во время сравнения свойств свойства типа функции и свойства с именами, начинающимися с $, игнорируются». docs.angularjs.org/api/ng/function/angular.equals
sonicwizard
2

Я знаю, что это довольно поздний ответ, но я только что потерял около получаса на отладку из-за этого. Это может сэкономить кому-то время.

БУДЬТЕ ВНИМАТЕЛЬНЫ, если вы используете angular.equals()объекты, у которых есть свойство obj.$something (имя свойства начинается с $), эти свойства будут проигнорированы при сравнении.

Пример:

var obj1 = {
  $key0: "A",
  key1: "value1",
  key2: "value2",
  key3: {a: "aa", b: "bb"}
}

var obj2 = {
  $key0: "B"
  key2: "value2",
  key1: "value1",
  key3: {a: "aa", b: "bb"}
}

angular.equals(obj1, obj2) //<--- would return TRUE (despite it's not true)
DanteTheSmith
источник