是否可以覆盖 ng-submit?
Is it possible to override ng-submit?
我正在寻找一种覆盖 ng-submit 的方法,以便它在 evaluating/running 它包含的表达式之前执行一些功能。例如,我想执行以下操作。
1) 将所有字段设置为脏(或可能已触及),以便即使用户跳过了所有字段也会对其进行验证。
2) 检查所有字段是否有效。如果不是就不要继续。
3) 如果有任何字段无效,则滚动第一个无效字段并将其聚焦。
我发现了一些执行此操作的一些指令,一些创建了新的元素指令,但 none 实际上 override/extend ngSubmit 所以我想知道这是否可能?
这段代码应该可以帮助您入门,因为它解决了条件 1、2 并为您提供了条件 3 的钩子。
至于滚动到无效字段,我还没有 tried/needed 但听起来很有趣。我想你可能真的会感到无聊并创建一个完整的 "form wrapper directive",尽管这看起来有点矫枉过正..
我只想使用可以在我的控制器中调用的服务方法。您是否只想滚动到第一个无效字段并聚焦它?
模板
<!-- 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
};
首先,元素不需要 "touched" 才能进行验证(关于第 1 点)。例如,这将使输入无效,给定 $scope.test = "abcd";
和:
<input ng-model="test" ng-maxlength="3">
其次,#2 很容易通过 form.$valid
实现:
<form name="form1" ng-submit="form1.$valid && onSubmit()">
...
</form>
如果预提交逻辑比这更复杂,它could/should在控制器中完成,例如,在onSubmit()
函数中。
但是,如果您的预提交逻辑与视图相关(而不是与 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
}
})
}
}
}
});
编辑:
由于 link 函数执行的顺序,这里使用 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 确保该指令在内置 ngSubmit
之前注册 element.on("submit", ...)
,因此它可以首先进行事件处理。
我正在寻找一种覆盖 ng-submit 的方法,以便它在 evaluating/running 它包含的表达式之前执行一些功能。例如,我想执行以下操作。
1) 将所有字段设置为脏(或可能已触及),以便即使用户跳过了所有字段也会对其进行验证。
2) 检查所有字段是否有效。如果不是就不要继续。
3) 如果有任何字段无效,则滚动第一个无效字段并将其聚焦。
我发现了一些执行此操作的一些指令,一些创建了新的元素指令,但 none 实际上 override/extend ngSubmit 所以我想知道这是否可能?
这段代码应该可以帮助您入门,因为它解决了条件 1、2 并为您提供了条件 3 的钩子。
至于滚动到无效字段,我还没有 tried/needed 但听起来很有趣。我想你可能真的会感到无聊并创建一个完整的 "form wrapper directive",尽管这看起来有点矫枉过正..
我只想使用可以在我的控制器中调用的服务方法。您是否只想滚动到第一个无效字段并聚焦它?
模板
<!-- 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
};
首先,元素不需要 "touched" 才能进行验证(关于第 1 点)。例如,这将使输入无效,给定 $scope.test = "abcd";
和:
<input ng-model="test" ng-maxlength="3">
其次,#2 很容易通过 form.$valid
实现:
<form name="form1" ng-submit="form1.$valid && onSubmit()">
...
</form>
如果预提交逻辑比这更复杂,它could/should在控制器中完成,例如,在onSubmit()
函数中。
但是,如果您的预提交逻辑与视图相关(而不是与 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
}
})
}
}
}
});
编辑:
由于 link 函数执行的顺序,这里使用 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 确保该指令在内置 ngSubmit
之前注册 element.on("submit", ...)
,因此它可以首先进行事件处理。