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.

Author: isherwood, 2015-02-23

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.

 51
Author: New Dev,
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

 7
Author: Dayan Moreno Leon,
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()">
 7
Author: Lorenzo Meriggi,
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');
    });
}
 0
Author: Eydrian,
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