W Angular mógłbym mieć formularz, który wygląda następująco:
<ng-form>
<label>First Name</label>
<input type="text" ng-model="model.first_name">
<label>Last Name</label>
<input type="text" ng-model="model.last_name">
</ng-form>
W ramach odpowiedniego kontrolera mogłem łatwo obserwować zmiany w treści tego formularza, takie jak:
function($scope) {
$scope.model = {};
$scope.$watch('model', () => {
// Model has updated
}, true);
}
Oto przykład Angular w JSFiddle .
Mam problem ze zrozumieniem, jak osiągnąć to samo w Angular. Oczywiście nie mamy już $scope
$ rootScope. Z pewnością istnieje metoda, dzięki której można osiągnąć to samo?
(ngModelChange)="onModelChange($event)"
atrybut do każdego pola wejściowego w formularzu, aby to osiągnąć?Odpowiedzi:
UPD. Odpowiedź i wersja demonstracyjna są aktualizowane, aby były zgodne z najnowszą wersją Angular.
Możesz subskrybować całe zmiany formularza ze względu na fakt, że FormGroup reprezentujący formularz udostępnia
valueChanges
właściwość będącą instancją Observerable:W takim przypadku musisz utworzyć formularz ręcznie przy użyciu FormBuilder . Coś takiego:
Sprawdź
valueChanges
w akcji w tym demo : http://plnkr.co/edit/xOz5xaQyMlRzSrgtt7Wn?p=previewźródło
valueChanges
emitera zdarzeń formularza, jeśli ten formularz jest zdefiniowany wyłącznie w szablonie? Innymi słowy - czy w konstruktorze składnika nie można uzyskać odniesienia do formularza, który został zdefiniowany wyłącznie w szablonie tego składnika, a nie za pomocą FormBuildera?@ViewChild()
. Zobacz moją zaktualizowaną odpowiedź.Jeśli używasz
FormBuilder
, zobacz odpowiedź @ dfsq.Jeśli nie używasz
FormBuilder
, istnieją dwa sposoby powiadamiania o zmianach.Metoda 1
Jak omówiono w komentarzach do pytania, użyj powiązania zdarzenia dla każdego elementu wejściowego. Dodaj do swojego szablonu:
Następnie w swoim komponencie:
Strona Formularze zawiera dodatkowe informacje o ngModel, które są istotne tutaj:
W twoim przypadku przypuszczam, że chcesz zrobić coś specjalnego.
Metoda 2
Zdefiniuj zmienną szablonu lokalnego i ustaw ją na
ngForm
.Użyj ngControl na elementach wejściowych.
Uzyskaj odwołanie do dyrektywy NgForm formularza za pomocą @ViewChild, a następnie zasubskrybuj ControlGroup NgForm w celu wprowadzenia zmian:
plunker
Aby uzyskać więcej informacji na temat metody 2, zobacz wideo Savkina .
Zobacz także odpowiedź @ Thierry, aby uzyskać więcej informacji na temat tego, co możesz zrobić z
valueChanges
obserwowalnym (np. Odbicia / odczekania trochę przed przetworzeniem zmian).źródło
Aby uzupełnić nieco więcej poprzednich świetnych odpowiedzi, musisz mieć świadomość, że formularze wykorzystują obserwowalne do wykrywania i obsługi zmian wartości. To coś naprawdę ważnego i potężnego. Zarówno Mark, jak i dfsq opisali ten aspekt w swoich odpowiedziach.
Observables pozwalają nie tylko na użycie
subscribe
metody (coś podobnego dothen
metody obietnic w Angular 1). W razie potrzeby możesz przejść dalej, aby zaimplementować niektóre łańcuchy przetwarzania dla zaktualizowanych danych w formularzach.Chodzi mi o to, że na tym poziomie można określić czas odbicia
debounceTime
metodą. Pozwala to odczekać pewien czas przed obsługą zmiany i poprawnie obsłużyć kilka danych wejściowych:Możesz również bezpośrednio podłączyć przetwarzanie, które chcesz wyzwolić (na przykład asynchroniczne), gdy wartości są aktualizowane. Na przykład, jeśli chcesz obsłużyć wartość tekstową w celu przefiltrowania listy na podstawie żądania AJAX, możesz skorzystać z
switchMap
metody:Możesz nawet posunąć się dalej, łącząc zwrócone obserwowalne bezpośrednio z właściwością swojego komponentu:
i wyświetl go za pomocą
async
potoku:Powiem tylko, że musisz pomyśleć o sposobie obsługi formularzy w inny sposób w Angular2 (o wiele potężniejszy sposób ;-)).
Mam nadzieję, że ci to pomoże, Thierry
źródło
Rozwijając sugestie Marka ...
Metoda 3
Zaimplementuj w modelu wykrywanie „głębokich” zmian. Zalety polegają głównie na unikaniu włączania aspektów interfejsu użytkownika do komponentu; obejmuje to również zmiany programowe wprowadzone w modelu. To powiedziawszy, wymagałoby dodatkowej pracy, aby zaimplementować takie rzeczy, jak debouncing, jak zasugerował Thierry, a to również wyłapie twoje własne zmiany programistyczne, więc używaj go ostrożnie.
Spróbuj w Plunker
źródło
Do
5+
wersji kątowej . Wprowadzenie wersji pomaga, ponieważ angular wprowadza wiele zmian.źródło
Myślałem o zastosowaniu metody (ngModelChange), potem pomyślałem o metodzie FormBuilder i ostatecznie zdecydowałem się na odmianę metody 3. Oszczędza to dekorowanie szablonu dodatkowymi atrybutami i automatycznie przejmuje zmiany w modelu - zmniejszając możliwość zapomnienia o czymś z metodą 1 lub 2.
Upraszczając nieco metodę 3 ...
Możesz dodać limit czasu, aby wywołać funkcję doSomething () tylko po x liczbie milisekund, aby zasymulować debounce.
źródło