Можно ли переопределить ng-submit?
Я ищу способ переопределить ng-submit, чтобы он выполнял некоторые функции перед оценкой / выполнением выражения, которое он содержит. Например, я хотел бы сделать следующее.
1) Установите все поля грязными (или, возможно, затронутыми), чтобы все поля были проверены, даже если пользователь пропустил их.
2) Убедитесь, что все поля проверены. Если нет, то не продолжайте.
3) Если какие-либо поля являются недействительными, прокрутите первое недействительное поле и сфокусируйте его.
Я нашел несколько директив, которые делают некоторые из них, некоторые создают новые директивы элементов, но ни одна из них не переопределяет / расширяет ngSubmit, поэтому мне интересно, возможно ли это?
2 ответа
Во-первых, элемент не нужно "трогать" для проверки правильности (это касается пункта № 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 здесь важен из-за порядка выполнения функции 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
делает это, так что он может иметь первый шаг при обработке событий.
Этот код должен помочь вам начать работу, поскольку он обращается к критериям № 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
};