Я создал директиву, которая генерирует поле ввода на основе метаданных ($scope.meta
). Моя проблема заключается в поддержке проверки формы angular.
Plunkr: http://plnkr.co/edit/AfR5cWyywGlCECS6h6Dr?p=preview
Объяснение: директива принимает параметр meta
, который описывает тип входного поля и другую связанную информацию для отображения поля. Все атрибуты, определенные в директиве, будут скопированы в элемент и, наконец, заменят директиву после компиляции и компоновки.
Вид:
<form name="userForm">
<!-- Username -->
<poly-field ng-model="storage" meta="meta" key="username" name="username" ng-minlength="3" ng-maxlength="8"></poly-field>
<p ng-show="userForm.username.$error.minlength" class="help-block">Username is too short.</p>
<p ng-show="userForm.username.$error.maxlength" class="help-block">Username too long</p>
<!-- Email -->
<poly-field ng-model="storage" meta="meta" key="email" name="email" ng-required></poly-field>
<p ng-show="userForm.email.$error.minlength" class="help-block">Email is too short.</p>
<p ng-show="userForm.email.$error.maxlength" class="help-block">Email is too long</p>
</form>
Ввод имени пользователя длиннее или короче разрешенного должен показать мне ошибку. Пропуск поля электронной почты также показывает мне ошибку.
Вот исходный код View после применения директивы:
<form name="userForm" class="ng-pristine ng-valid ng-valid-required">
<!-- Username -->
<input type="undefined" ng-model="storage.username" meta="meta" key="username" name="username" ng-minlength="3" ng-maxlength="8" class="ng-scope ng-valid-minlength ng-dirty ng-valid ng-valid-maxlength">
<p ng-show="userForm.username.$error.minlength" class="help-block ng-hide">Username is too short.</p>
<p ng-show="userForm.username.$error.maxlength" class="help-block ng-hide">Username too long</p>
<!-- Email -->
<input type="undefined" ng-model="storage.email" meta="meta" key="email" name="email" ng-required="" class="ng-scope ng-valid ng-valid-required ng-dirty">
<p ng-show="userForm.email.$error.minlength" class="help-block ng-hide">Email is too short.</p>
<p ng-show="userForm.email.$error.maxlength" class="help-block ng-hide">Email is too long</p>
</form>
Вот модель, с которой работает представление и директива, она объявлена в ParentCtrl.
$scope.storage = {
username: "Kitkat",
email: "[email protected]"
};
Это метаинформация, которая говорит о том, как выглядит поле ввода (это текст? дата? и т. д.)
$scope.meta = {
username: { type: "text" },
email: { type: "text" }
};
Декларация директивы:
app.directive('polyField', function($compile) {
var linkFn = function(scope, element, attributes) {
// create input element depending on the type
var template = document.createElement("input");
template.type = scope.storage[attributes.key].type;
// copy all attributes
for (var attr in attributes.$attr) {
if (attributes.$attr[attr] == 'ng-model') {
template.setAttribute('ng-model', attributes[attr] + '.' + attributes.key);
} else {
template.setAttribute(attributes.$attr[attr], attributes[attr]);
}
}
// template compilation, linking and element replacement
template = angular.element(template.outerHTML);
var linkTemplate = $compile(template);
var domElement = linkTemplate(scope);
element.replaceWith(domElement);
}
var directive = {
restrict: 'E',
scope: {
meta: '=',
storage: '=ngModel',
key: '=',
},
link: linkFn
};
return directive;
});
Некоторые мысли:
Каждая директива создает изолированную область, поэтому внутри директивы userForm
невидима, однако двусторонняя привязка storage
(ng-модель) видна из области директивы и родительской области, если userForm видит, что внутри storage
должно быть все в порядке, не так ли?
Я попытался передать userForm
в область действия директивы:
// directive
scope: {
meta: '=',
storage: '=ngModel',
key: '=',
userForm: '='
}
// template
<poly-field user-form="userForm" ng-model="storage" meta="meta" key="username" name="username" ng-minlength="3" ng-maxlength="8"></poly-field>
но без эффекта.
Когда я смотрю в область директив, в поле userForm
я вижу, что поле ввода на самом деле $dirty: false
, $invalid: true
, и что после того, как я ввел имя пользователя/адрес электронной почты,
В исходном коде кажется, что классы проверки применяются правильно: ng-valid-minlength
ng-dirty
ng-invalid
ng-invalid-maxlength
по-прежнему, ошибки проверки не отображаются.
Могу ли я что-нибудь с этим сделать?