简体   繁体   English

是否可以覆盖ng-submit?

[英]Is it possible to override ng-submit?

I'm looking for a way to override ng-submit so that it performs some functions before evaluating/running the expression it contains. 我正在寻找一种方法来覆盖ng-submit,以便它在评估/运行包含的表达式之前执行一些功能。 For example, I would like to do the following. 例如,我想执行以下操作。

1) Set all fields dirty (or perhaps touched) so that all fields are validated even if the user has skipped over them. 1)将所有字段设置为脏(或可能被触摸),以便即使用户跳过了所有字段也可以对其进行验证。

2) Check that all fields validate. 2)检查所有字段均有效。 If not then don't continue. 如果没有,请不要继续。

3) If any fields are invalid then scroll the first invalid field and focus it. 3)如果任何字段无效,则滚动第一个无效字段并将其聚焦。

I have found a few directives that do some of this, some create new element directives but none actually override/extend ngSubmit so I'm wondering if this is possible? 我发现有一些指令可以做到这一点,一些指令可以创建新的元素指令,但实际上并没有覆盖/扩展ngSubmit,所以我想知道这是否可能吗?

First, an element need not be "touched" for validation to work (that's about point #1). 首先,无需“触摸”某个元素即可使验证正常工作(这与第1点有关)。 For example, this would invalidate the input, given $scope.test = "abcd"; 例如,给定$scope.test = "abcd";这会使输入无效$scope.test = "abcd"; and: 和:

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

Second, #2 is easily achieved with form.$valid : 其次,使用form.$valid可以轻松实现#2:

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

If pre-submit logic is more complicated then this, it could/should be done in the controller, for example, in the onSubmit() function. 如果预提交逻辑更加复杂,则可以/应该在控制器中完成,例如在onSubmit()函数中。

But, if your pre-submit logic is View-related (as opposed to ViewModel-related) - and scrolling is View-related - then you could create another ngSubmit directive with higher priority and prevent default submit event handling: 但是,如果您的提交前逻辑与视图相关(而不是与ViewModel相关),并且滚动视图相关,那么您可以创建另一个具有更高优先级的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
          }
        })
      }
    }
  }
});

Demo 演示

EDIT: 编辑:

Using pre -link is important here due to order of link function executions. 由于链接功能的执行顺序,此处使用pre链接非常重要。 The order of execution is: 执行顺序为:

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

So, the use of higher priority and pre -link ensures that this directive registers element.on("submit", ...) before the built-in ngSubmit does it, so it can have a first go at event handling. 因此,使用更高优先级和pre链接可确保此指令在内置ngSubmit操作之前先注册element.on("submit", ...) ,这样它才可以进行事件处理。

This code should get you started as it addresses criterias number 1, 2 and gives you a hook for number 3. 该代码可以帮助您入门,因为它解决了标准1、2,并为您提供了3的钩子。

As for scrolling to the invalid fields, I have not tried/needed that yet but sounds interesting. 至于滚动到无效字段,我还没有尝试/需要,但是听起来很有趣。 I guess you can get real bored and create an entire "form wrapper directive", though seems like overkill.. 我想您可能会感到无聊,并创建了一个完整的“表单包装器指令”,尽管这似乎有些过头。

I would just use a service method that can be called in my controller. 我只会使用可以在控制器中调用的服务方法。 Are you thinking of just scrolling to the first invalid field and focusing it? 您是否在考虑滚动到第一个无效字段并将其聚焦?

Template 模板

<!-- 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>

Controller 调节器

vm.data = {};
vm.submit = function(isValid, data) {
    if (!isValid) { 
        //Scroll to bad field
        return; 
    }
    // Do form submission via service
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM