Porównaj obiekty w Angular

79

Czy w Angular można zrobić „głębokie” porównanie dwóch obiektów? Chciałbym porównać każdą parę klucz / wartość. Na przykład:

Przedmiot 1

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

Obiekt 2

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

To, czego potrzebuję, to niepowodzenie porównania, ponieważ tylko jedna z par klucz / wartość jest różna. Innymi słowy, WSZYSTKIE pary klucz / wartość muszą dokładnie pasować, w przeciwnym razie wystąpi błąd. Czy to jest już wbudowane w Angular? Jestem pewien, że mógłbym napisać własny serwis, gdybym naprawdę tego potrzebował, ale miałem nadzieję, że został już wbudowany. Podobnie jak angular.equals.

selanac82
źródło

Odpowiedzi:

205

Aby porównać dwa obiekty, możesz użyć:

angular.equals(obj1, obj2)

Robi głębokie porównanie i nie zależy od kolejności kluczy Zobacz AngularJS DOCS i trochę Demo

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
klode
źródło
6
Zauważ, że angular.equals testuje tożsamość, a nie równość . TL; DR:angular.equals( { id: "12" }, { id: 12 } ) // is false
bobjones
@bobjones angular.equals zwraca wartość true na podstawie tożsamości LUB głębokiej równości, więc proponowany przykład zwróci wartość true. zobacz dokumentację angular.equals , a konkretnie Dwa obiekty lub wartości są uważane za równoważne, jeśli przynajmniej jedno z poniższych jest prawdziwe
tommyTheHitMan
5
@tommyTheHitMan: przykład bobjones zwraca, falseponieważ na podstawie tożsamości "12"===12 // is false. Po prostu to wypróbuj.
klode
A jeśli potrzebujesz obiektu różnicowego do śledzenia historii wycofań
Mark
4
Krótka uwaga: angular.equals () ignoruje wszystkie właściwości zaczynające się od $ i wszystkie właściwości, których wartościami są funkcje, gdy oba argumenty są obiektami.
im1dermike
24

Zakładając, że kolejność jest taka sama w obu obiektach, po prostu stringifyje oba i porównaj!

JSON.stringify(obj1) == JSON.stringify(obj2);
tymeJV
źródło
14
angular.equals (obj1, obj2) również powinno działać. Nie zależy od kolejności kluczy i jest głęboki (nazywa się to rekurencyjnie) code.angularjs.org/1.2.0/docs/api/angular.equals
klode
4
To byłoby bardzo złe założenie!
zasada holograficzna
1
angular.toJsonusunie również $$ hashKeys
5

Trochę za późno w tym wątku. angular.equals robi głębokie sprawdzenie, ale czy ktoś wie, dlaczego zachowuje się inaczej, jeśli jeden z elementów zawiera przedrostek „$”?

Możesz wypróbować to demo z następującymi danymi wejściowymi

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);
KM.
źródło
4
Z dokumentacji Angulara: „Podczas porównywania właściwości właściwości typu funkcji i właściwości o nazwach zaczynających się od znaku $ są ignorowane”. docs.angularjs.org/api/ng/function/angular.equals
sonicwizard
2

Wiem, że to trochę późna odpowiedź, ale właśnie straciłem około pół godziny debugowania z tego powodu. Może to zaoszczędzić komuś trochę czasu.

BĄDŹ UWAŻNY, jeśli używasz angular.equals()obiektów, które mają właściwość obj.$something (nazwa właściwości zaczyna się od $), te właściwości zostaną zignorowane w porównaniu.

Przykład:

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
źródło