funkcjonalność podobna do ngChange dla całego formularza
Chciałbym zrobić odpowiednik ng-change
dla całego formularza za każdym razem, gdy nastąpi zmiana w jednym z jego pól wejściowych.
Wiem, że od AngularJS 1.3 mam opcję debounce, ale dotyczy to tylko jednego wejścia.
Szukam funkcjonalności "debounce" / "on change", która będzie miała zastosowanie do całego formularza.
4 answers
Nie ma wbudowanego sposobu wykonania ng-change
dla formularza.
To może nawet nie być potrzebne, ponieważ jeśli uporządkowałeś swój model widoku prawidłowo, wtedy Dane wejściowe formularza są prawdopodobnie powiązane z pewną właściwością scope-exposed: {]}
$scope.formData = {};
I w widoku:
<form name="form1">
<input ng-model="formData.a">
<input ng-model="formData.b">
</form>
Następnie możesz uważnie obserwować (z $watch
) zmiany modelu (i zastosować dowolną opcję debounce na elementach, których potrzebujesz):
$scope.$watch("formData", function(){
console.log("something has changed");
}, true);
Problem polega oczywiście na tym, że jest to głęboka obserwacja i to jest drogi. Ponadto reaguje nie tylko na zmiany w formie, ale także na zmianę formData
z dowolnego źródła.
Więc, jako alternatywę, możesz stworzyć własną dyrektywę, aby komplementować formę i reagować na zmiany formy.
.directive("formOnChange", function($parse){
return {
require: "form",
link: function(scope, element, attrs){
var cb = $parse(attrs.formOnChange);
element.on("change", function(){
cb(scope);
});
}
}
});
A użycie to:
<form name="form1" form-on-change="doSomething()">
<input ng-model="formData.a">
<input ng-model="formData.b">
</form>
Plunker do ilustracji.
Zauważ, że zdarzenie "change" jest wywoływane tylko przy rozmyciu dla wejścia tekstu, zgodnie z dokumentacja jQuery:
Zdarzenie
change
jest wysyłany do elementu, gdy zmienia się jego wartość. To zdarzenie jest ograniczone do elementów<input>
, pól<textarea>
i elementów<select>
. W przypadku pól wyboru, pól wyboru i przycisków opcji zdarzenie jest wywoływane natychmiast, gdy użytkownik dokonuje zaznaczenia za pomocą myszy, ale dla innych typów elementów zdarzenie jest odroczone do momentu utraty ostrości elementu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-06 15:52:54
Jeden "hacky" sposób, aby to zrobić jest ustawiając watcher do formularza brudne, ważne w zależności od wymagań można zrobić coś w rodzaju
$scope.$watch('form.$dirty',function(v){
if(!v){return}
form.$setPristine()
/*do something here*/
})
Będzie to wykonywane za każdym razem, gdy formularz zostanie zmodyfikowany, jeśli chcesz wykonać kod tylko na poprawnym zmodyfikowanym formularzu, możesz to zrobić
if(!v || form.$invalid){return}
I jeśli chcesz wykonać kod tylko wtedy, gdy formularz przechodzi do $valid state, wystarczy skonfigurować obserwatora dla ' form.$valid '
Jeśli nie lubisz zanieczyszczać swojego lunety obserwatorami, to zawsze może utworzyć dyrektywę wokół formularza, która wyświetla Zdarzenie API przy zmianie i wewnętrznie zajmuje się obserwatorem
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-17 12:23:09
Zgodnie z komentarzem Erica Soyke możesz podłączyć sprawdzanie zmiany formularza podczas zdarzenia keyup.
W ten sposób można po prostu użyć wbudowanej dyrektywy ng-keyup:
<form name="form1" ng-keyup="doSomething()">
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-06 11:29:38
/ Align = "center" bgcolor = "# e0ffe0 " / cesarz chin / / align = center / .. ale to działa całkiem nieźle
// html
<form name="$ctrl.form">...</form>
// controller
function $postLink() {
ctrl.form.$$element.on('change', function () {
console.log('fired');
});
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-10 12:26:20