2

我正在寻找一种覆盖 ng-submit 的方法,以便它在评估/运行它包含的表达式之前执行一些功能。例如,我想做以下事情。

1)将所有字段设置为脏(或可能被触及),以便即使用户跳过了所有字段,也可以验证所有字段。

2) 检查所有字段是否有效。如果没有,请不要继续。

3) 如果任何字段无效,则滚动第一个无效字段并将其聚焦。

我发现了一些执行此操作的指令,一些创建了新的元素指令,但没有一个实际上覆盖/扩展 ngSubmit,所以我想知道这是否可能?

4

2 回答 2

4

首先,不需要“触摸”一个元素来进行验证(这大约是第 1 点)。例如,这将使输入无效,给定$scope.test = "abcd";并且:

<input ng-model="test" ng-maxlength="3">

其次,#2很容易实现form.$valid

<form name="form1" ng-submit="form1.$valid && onSubmit()">
  ...
</form>

如果预提交逻辑比这更复杂,它可以/应该在控制器中完成,例如在onSubmit()函数中。

但是,如果您的预提交逻辑与 View 相关(而不是与 ViewModel 相关) - 并且滚动View 相关 - 那么您可以创建另一个ngSubmit具有更高优先级的指令并阻止默认提交事件处理:

.directive("ngSubmit", function() {
  return {
    require: "?form",
    priority: 10,
    link: {
      pre: function(scope, element, attrs, form) {
        element.on("submit", function(event) {        
          if (form && !form.$valid) {
            event.stopImmediatePropagation();
            event.preventDefault();

            // do whatever you need to scroll here
          }
        })
      }
    }
  }
});

演示

编辑:

pre由于链接函数执行的顺序,在这里使用-link 很重要。执行顺序为:

1. pre-link of parent or higher priority directive
2. pre-link of child or lower priority directive
3. post-link of child or lower priority directive
4. post-link of parent or higher priority directive

因此,使用更高优先级和pre-link 可确保该指令element.on("submit", ...)在内置指令之前注册ngSubmit,因此它可以先进行事件处理。

于 2015-05-24T17:01:56.223 回答
1

这段代码应该可以帮助您入门,因为它解决了标准 1、2 并为您提供了数字 3 的钩子。

至于滚动到无效字段,我还没有尝试/需要,但听起来很有趣。我猜你可能会感到无聊并创建一个完整的“表单包装器指令”,虽然看起来有点矫枉过正..

我只会使用可以在我的控制器中调用的服务方法。您是否只想滚动到第一个无效字段并聚焦它?

模板

<!-- Form Template -->
<form name="form" novalidate ng-submit="vm.submit(form.$valid, vm.data)">
    <input type="text"
           name="blah"
           ng-model="vm.data.blah"
           ng-model-options="{debounce: {'default': 300, blur: 0}}"
           required
           formnovalidate/>
     <div ng-messages="form.blah.$error"
          ng-messages-include="messages.html"
          ng-if="form.$submitted || form.blah.$touched">
     </div>
    <button type="submit">Submit</button>
</form>

<!-- messages.html -->
<div ng-message="required">This field is required</div>

控制器

vm.data = {};
vm.submit = function(isValid, data) {
    if (!isValid) { 
        //Scroll to bad field
        return; 
    }
    // Do form submission via service
};
于 2015-05-24T16:44:30.573 回答