2013-03-15 13 views
96

Załóżmy, że chciałbym zrobić coś takiego, jak automatycznie uruchamiać kod (na przykład zapisywanie danych na serwerze) za każdym razem, gdy zmieniają się wartości modelu. Czy jest to jedyny sposób, ustawiając coś w rodzaju kontrolki, która może zmienić model?AngularJS: automatycznie wykrywa zmianę w modelu

Tj., Z widokami, rzeczy zmieniają się w prawo, gdy model jest zmieniany bez konieczności wyraźnego podpinania czegokolwiek. Czy istnieje odpowiednik na uruchamianie kodu, który zapisuje na serwerze? Coś podobnego do tego, co widzisz z kręgosłupem.

Odpowiedz

142

W widokach z {{}} i/lub ng-model Angular ustawia dla Ciebie $watch() es za kulisami.

Domyślnie $watch porównuje się przez odniesienie. Jeśli ustawisz trzeci parametr na $watch na true, Angular zamiast tego "spłyci" będzie obserwował obiekt w celu zmiany. W przypadku tablic oznacza to porównywanie elementów tablicy, w przypadku map obiektowych oznacza to oglądanie właściwości. Tak to powinno robić, co chcesz:

$scope.$watch('myModel', function() { ... }, true); 

Aktualizacja: kątowe v1.2 dodaje nową metodę do tego, `$watchCollection():

$scope.$watchCollection('myModel', function() { ... }); 

zauważyć, że słowo "płytkie" jest używany do opisania Porównanie raczej niż "głębokie", ponieważ odniesienia nie są przestrzegane - np. jeśli obserwowany obiekt zawiera wartość właściwości, która jest odniesieniem do innego obiektu, to odniesienie nie jest stosowane w celu porównania innego obiektu.

+1

Ah, świetnie! Czy istnieje jakikolwiek powód, dla którego nie wydaje się, że wszystko to udokumentowane (tj. Nie sądzę, że któryś z tutoriali na tej kanciastej stronie wspomniał o ustawianiu zegarków $ bezpośrednio)? Czy jest coś złego w tym, że skonfigurowanie (potencjalnie wielu) haków 'ng-change' na kontrolkach wejściowych byłoby lepszym pomysłem? – Alec

+12

Tak, byłoby miło, gdyby główny tutorial wspomniał gdzieś o $ $.To, co jest "złe" w tym podejściu, to to, że może być czasochłonne, jeśli twój model jest duży (każdy cykl trawienia - każde naciśnięcie klawisza w polu wejściowym - spowoduje, że ten model będzie poddany głębokiemu zanieczyszczeniu, prawdopodobnie wiele razy) . W takim przypadku lepiej byłoby wybrać selektywne $ watch() lub selektywną zmianę ng. –

7

A jeśli trzeba projektować swoje elementy formularza według swojego stanu (zmodyfikowany/niemodyfikowane) dynamicznie lub sprawdzić, czy pewne wartości rzeczywiście zmieniły, można użyć następujących modułów, opracowaną przez siebie: https://github.com/betsol/angular-input-modified

Dodaje dodatkowe właściwości i metody do formularza i jego elementów potomnych. Za jego pomocą można sprawdzić, czy jakiś element zawiera nowe dane, czy nawet sprawdzić, czy cały formularz zawiera nowe niezapisane dane.

Możesz ustawić następujący zegarek: $scope.$watch('myForm.modified', handler) i twój przewodnik zostanie wywołany, jeśli niektóre elementy formularza rzeczywiście zawierają nowe dane lub jeśli zostały odwrócone do stanu początkowego.

Można również użyć właściwości poszczególnych elementów formularza, aby zmniejszyć ilość danych wysyłanych do serwera za pośrednictwem wywołania AJAX. Nie ma potrzeby wysyłania niezmienionych danych.

Jako bonus można przywrócić formularz do stanu początkowego, wywołując metodę formularza reset().

można znaleźć demo modułu jest tutaj: http://plnkr.co/edit/g2MDXv81OOBuGo6ORvdt?p=preview

Cheers!

+0

Czy istnieje sposób, aby to sprawdzić w kontrolerze. na przykład, jeśli klikniesz przycisk x, czy mogę zrobić jak popup popup (myform.modified) z potwierdzeniem wyświetlenia? – Flash

+0

Oczywiście, wystarczy przekazać FormController do funkcji kontrolera: '

', '
+0

dzięki temu zrobi coś tylko wtedy, gdy formularz został zmodyfikowany, prawda? – Flash

Powiązane problemy