Это надуманный пример, но один, который демонстрирует проблему, я встречая.Угловая (сфера?), что требует, чтобы родитель FormController
У меня есть форма, которая имеет вход, который генерируется с использованием директивы. Код выглядит следующим образом. скрипку здесь http://jsfiddle.net/technicolorenvy/CFynn/2/
Посмотреть
<div ng-controller="AppController">
<form name="myForm">
<input name="myInput" id="myInput" ng-model="myInputModel" ng-pattern="/\d+/" my-directive required/>
<button type="submit" ng-click="submitForm()">Submit</button>
</form>
</div>
Контроллер
app.controller('AppController', function ($scope) {
$scope.submitForm = function() {
console.log('form controller inside AppController submitForm()');
console.log(angular.copy($scope.myForm));
console.log('is the form valid? ' + $scope.myForm.$valid);
console.log(' ');
};
});
Директива
app.directive('myDirective', function() {
return {
template: '<div><input/></div>',
replace: true,
restrict: 'A',
require: '^form',
compile: function (element, attrs) {
// some setup here
// move the id and ng-model down onto the enclosed input
element.removeAttr('id').removeAttr('ng-model').removeAttr('name');
element.find('input').attr('id', attrs.id).attr('ng-model', attrs.ngModel).attr('name', attrs.name);
var inputName = attrs.name,
$input = element.find('input');
if (attrs.required) {
element.removeAttr('required');
$input.attr('required', true);
}
if (attrs.ngPattern) {
element.removeAttr('ng-pattern');
$input.attr('ng-pattern', attrs.ngPattern);
}
return {
pre: function (scope, element, attrs, formCtrl) {
var patternErrs,
fakeNum = 1234;
$input.on('change', function() {
patternErrs = formCtrl.$error.pattern;
if (patternErrs && patternErrs.length > 0) {
angular.forEach(patternErrs, function (err) {
if (err.$name === inputName) {
$input.val(fakeNum);
formCtrl[inputName].$setViewValue(fakeNum);
formCtrl[inputName].$setValidity('pattern', true);
}
});
}
console.log('formCtrl inside directive');
console.log(angular.copy(formCtrl));
console.log('is the form valid? ' + formCtrl.$valid);
console.log(' ');
});
}
};
}
}
});
В директиве у меня есть событие OnChange на 'генерируемой' вход, который проверяет наличие шаблона ошибки, соответствующие имени этого ввода, тогда, если есть, сила данные должны быть то, что нам нужно с поддельным значением, с использованием setViewValue
, а затем установить срок действия с использованием setValidity
.
Это работает ... вроде. Проблема заключается в том, что в FIRST submit форма всегда недействительна. Вы должны нажать кнопку Отправить TWICE, чтобы форма считалась действительной. (Шаги включены ниже)
- Введите строку (например, «ABCD») на входе
- вход не проходит проверку шаблона, а затем получает действительное значение (1234)
- директиву «myDirective» обрабатывает этот + устанавливает значение входного и валидность в
- на ПЕРВОМ заполните, однако, форма является недействительной
- на втором представить без изменения ввода, форма действует
Итак, как я могу сделать форму действительной при первом отправке? БЕЗ симулирования действительности формы (читайте, я не хочу, чтобы вручную была установлена форма, чтобы она была действительной). Это похоже на проблему, но если да, я не слишком уверен, как ее исправить.
Спасибо!
Опять же, супер надуманный пример. реальный случай это. У меня есть директива, которая будет создавать входы, которые используют директиву bs-datepicker. улов по умолчанию, bs-datepicker приходит в несколько горячий и обновит атрибут value элемента до текущего дня, если введен неверный текст. После этого bs-datepicker добавит коллекцию дат в formController. $ Error и input. $ Errors collections. Но интерфейс плох. Поскольку он _looks_, как будто у вас есть действительный ввод. Мое намерение заключалось в том, чтобы использовать пользовательский интерфейс «default», предоставляемый bs-datepicker, но на самом деле массировать его таким образом, чтобы он был действительным – technicolorenvy
, основываясь на вышесказанном, является ли это еще более важным способом сделать это? – technicolorenvy
Хм, это сложно ... Вам может быть лучше изменить директиву bsdatepicker в соответствии с вашими потребностями. Это может быть так же просто, как изменение его приоритета или, возможно, переупорядочение функций проверки в nsModel $ parsers и $ formatters. Моя кишка говорит мне, что в любое время, когда у вас есть директива, просто перетасовывая атрибуты и обманывая другую директиву, вы можете * лаять на неправильное дерево. В конце концов, все, что работает, лучше. Однако что бы ни было * проверяемым * и работает * еще лучше *. –