Is it possible to override ng-submit?

时光毁灭记忆、已成空白 提交于 2019-12-12 10:06:00

问题


I'm looking for a way to override ng-submit so that it performs some functions before evaluating/running the expression it contains. 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.

2) Check that all fields validate. If not then don't continue.

3) If any fields are invalid then scroll the first invalid field and focus it.

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?


回答1:


First, an element need not be "touched" for validation to work (that's about point #1). For example, this would invalidate the input, given $scope.test = "abcd"; and:

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

Second, #2 is easily achieved with form.$valid:

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

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:

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




回答2:


This code should get you started as it addresses criterias number 1, 2 and gives you a hook for number 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
};


来源:https://stackoverflow.com/questions/30425605/is-it-possible-to-override-ng-submit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!