整个表单的类似 ngChange 的功能

ngChange-like functionality for the entire form

每当其中一个输入字段发生变化时,我想对整个表单执行相当于 ng-change 的操作。

我知道自 AngularJS 1.3 以来我有去抖动选项,但它仅适用于单个输入。

我正在寻找适用于整个表单的 "debounce"/"on change" 功能。

一种 "hacky" 方法是将观察者设置为 dirty, valid 的形式,具体取决于您的要求,您可以这样做

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

这将在每次修改表单时执行,如果您只想在有效的修改表单上执行代码,您可以这样做

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

如果您只想在表单进入 $valid 状态时执行您的代码,只需为 'form.$valid'

设置您的观察者

如果您不想让观察者污染您的作用域,您始终可以围绕表单创建一个指令,该指令公开一个变化 api 事件并在内部处理观察者

没有内置的方法来 ng-change 表单。

甚至可能不需要它,因为如果您正确地组织了视图模型,那么您的表单输入很可能会绑定到某个公开的范围 属性:

$scope.formData = {};

并在视图中:

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

然后您可以深入观察(使用 $watch)模型更改(并在您需要的元素上应用任何去抖动选项):

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

那么问题是,当然,这是一款深表,而且价格昂贵。此外,它不仅对表单的变化做出反应,而且对来自任何来源的 formData 的变化做出反应。

因此,作为替代方案,您可以创建自己的指令来补充表单并对表单的更改事件做出反应。

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

用法是:

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

plunker 用于说明。

请注意,根据 jQuery documentation:

,"change" 事件仅在文本输入模糊时触发

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.

根据 Eric Soyke 的评论,您可以在 keyup 事件上连接表单更改的检查。

这样你就可以简单地使用内置指令 ng-keyup:

<form name="form1" ng-keyup="doSomething()">

好的,超级超级迟到的答案......但这工作非常整洁

// html
<form name="$ctrl.form">...</form>

// controller
function $postLink() {
    ctrl.form.$$element.on('change', function () {
        console.log('fired');
    });
}