ngChange-like functionality for the entire form

后端 未结 4 1963
余生分开走
余生分开走 2020-12-05 04:21

I would like to do an equivalent of ng-change for the entire form whenever there is a change in one of its input fields.

I know that since AngularJS 1.3

相关标签:
4条回答
  • 2020-12-05 04:48

    As per Eric Soyke comment you could hook up the check of the form change on the keyup event.

    This way you could simply use the builtin directive ng-keyup:

    <form name="form1" ng-keyup="doSomething()">
    
    0 讨论(0)
  • 2020-12-05 04:49

    There isn't a built-in way to do ng-change for a form.

    It may not even be needed, because if you organized your view model properly, then your form inputs are likely bound to a certain scope-exposed property:

    $scope.formData = {};
    

    and in the View:

    <form name="form1">
      <input ng-model="formData.a">
      <input ng-model="formData.b">
    </form>
    

    Then you could deep-watch (with $watch) for model changes (and apply whatever debounce option on elements that you need):

    $scope.$watch("formData", function(){
      console.log("something has changed");
    }, true);
    

    Then problem is, of course, that this is a deep-watch and it is expensive. Also, it reacts not only to changes in the Form, but also to a change in formData from any source.

    So, as an alternative, you could create your own directive to compliment the form and react to form's change events.

    .directive("formOnChange", function($parse){
      return {
        require: "form",
        link: function(scope, element, attrs){
           var cb = $parse(attrs.formOnChange);
           element.on("change", function(){
              cb(scope);
           });
        }
      }
    });
    

    and the usage is:

    <form name="form1" form-on-change="doSomething()">
      <input ng-model="formData.a">
      <input ng-model="formData.b">
    </form>
    

    plunker for illustration.

    Note, that the "change" event is fired only on blur for a text input, as per jQuery documentation:

    The change event is sent to an element when its value changes. This event is limited to <input> elements, <textarea> boxes and <select> elements. For select boxes, checkboxes, and radio buttons, the event is fired immediately when the user makes a selection with the mouse, but for the other element types the event is deferred until the element loses focus.

    0 讨论(0)
  • 2020-12-05 04:54

    okay, super super late answer ... but this works pretty neat

    // html
    <form name="$ctrl.form">...</form>
    
    // controller
    function $postLink() {
        ctrl.form.$$element.on('change', function () {
            console.log('fired');
        });
    }
    
    0 讨论(0)
  • 2020-12-05 04:57

    one "hacky" way to do this is by setting a watcher to the form dirty, valid depending on your requirements you can do something like

       $scope.$watch('form.$dirty',function(v){
             if(!v){return}
             form.$setPristine()
             /*do something here*/
        })
    

    this will execute everytime the form gets modified, if you only want to execute your code on valid modified form you can do

           if(!v || form.$invalid){return}
    

    and if you only want to execute your code when the form steps to $valid state just need to set up your watcher for 'form.$valid'

    if you don't like to pollute your scope with watchers, you can always create a directive around the form that exposes a on-change api event and internally takes care of the watcher

    0 讨论(0)
提交回复
热议问题