Angularjs: проверка формы и директива ввода
Я создал директиву в приложении AngularJS, которая создает стилизованный ввод в моем приложении. Это выглядит так:
AC.directive('formInput',function ($compile) {
return {
transclude: true,
replace: true,
scope:{},
templateUrl: '/views/partials/form/input.html',
restrict: 'E',
link: function(scope, element, attrs){
scope.opts = attrs;
if(attrs.ngModel){
element.find('input').attr('ng-model', attrs.ngModel);
$compile(element.contents())(scope.$parent);
}
if(!attrs.type){
scope.opts.type = 'text';
}
}
};
}
)
И шаблон для этого:
<label class="acxm-textfield {{opts.cssclass}}">
<span ng-bind="opts.labeltext"></span>
<input type="{{opts.type}}" name="{{opts.inputname}}" value="{{opts.inputvalue}}" placeholder="{{opts.placeholder}}" ng-maxlength="{{opts.maxLength}}"/>
</label>
Звонок прост:
<form-input ng-model="UserProfile.FirstName" max-length="50" labeltext="{{'GENERAL.name' | translate}}" cssclass="acxm-p-horizontal" inputname="name" inputvalue="{{UserProfile.FirstName}}"></form-input>
Я хотел создать проверку для этого поля и добавил информацию об ошибке:
<span ng-show="showError(userInfoForm.name,'email')">
You must enter a valid email
</span>
И showError это:
$scope.showError = function(ngModelController, error) {
return ngModelController.$error[error];
};
По сути, оно скопировано из книги "Освоение разработки веб-приложений с помощью AngularJS". У меня есть проблема, потому что, когда я регистрирую свою форму, какое имя userInfoForm
в консоль попал {{opts.inputname}}
вместо свойства name, значение которого здесь должно быть "name". Что я делаю неправильно?
2 ответа
Попробуй мой dynamic-name
директива здесь: проверка поля формы AngularJS
замещать name="{{opts.inputname}}"
с dynamic-name="opts.inputname"
Я также упростил ваш код для демонстрации:
app.directive("dynamicName", function($compile) {
return {
restrict: "A",
terminal: true,
priority: 1000,
link: function(scope, element, attrs) {
var name = scope.$eval(attrs.dynamicName);
if (name) {
element.attr('name', name);
element.removeAttr("dynamic-name");
$compile(element)(scope);
}
}
};
});
app.directive('formInput', function($compile) {
return {
replace: true,
scope: {},
templateUrl: 'formInput.html',
restrict: 'E',
link: function(scope, element, attrs) {
scope.opts = attrs;
$compile(element.contents())(scope);
}
}
});
Шаблон ввода формы:
<label class="acxm-textfield {{opts.cssclass}}">
<span ng-bind="opts.labeltext"></span>
<input type="{{opts.type}}" dynamic-name="opts.inputname" ng-model="opts.inputvalue"
placeholder="{{opts.placeholder}}"
ng-maxlength="{{opts.maxLength}}" required/> //use dynamic-name directive to bind dynamic names.
</label>
ДЕМО (попробуйте очистить текст, чтобы увидеть проверку, я использовал необходимую проверку для быстрой демонстрации, вы можете изменить код на проверку по электронной почте). Ключ использует dynamic-name
директивы.
Вот еще один пример использования директив проверки формы / имени
<form name="myFormName">
<nested directives of many levels>
ex: <input ng-repeat=(index, variable) in variables" type="text"
my-name="{{ variable.name + '/' + 'myFormName' }}"
ng-model="variable.name" required />
ex: <select ng-model="variable.name" ng-options="label in label in {{ variable.options }}"
my-name="{{ variable.name + '/' + 'myFormName' }}"
</select>
</form
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
app.directive('rsName', function(){
var rsNameError = "rsName directive error: "
return {
restrict:'A', // Declares an Attributes Directive.
require: 'ngModel', // ngModelController.
link: function( scope, elem, attrs, ngModel ){
if( !ngModel ){ return } // no ngModel exists for this element
// check rsName input for proper formatting ex. something/something
checkInputFormat(attrs);
var inputName = attrs.rsName.match('^\\w+').pop(); // match upto '/'
assignInputNameToInputModel(inputName, ngModel);
var formName = attrs.rsName.match('\\w+$').pop(); // match after '/'
findForm(formName, ngModel, scope);
} // end link
} // end return
function checkInputFormat(attrs){
if( !/\w\/\w/.test(attrs.rsName )){
throw rsNameError + "Formatting should be \"inputName/formName\" but is " + attrs.rsName
}
}
function assignInputNameToInputModel(inputName, ngModel){
ngModel.$name = inputName
}
function addInputNameToForm(formName, ngModel, scope){
scope[formName][ngModel.$name] = ngModel; return
}
function findForm(formName, ngModel, scope){
if( !scope ){ // ran out of scope before finding scope[formName]
throw rsNameError + "<Form> element named " + formName + " could not be found."
}
if( formName in scope){ // found scope[formName]
addInputNameToForm(formName, ngModel, scope)
return
}
findForm(formName, ngModel, scope.$parent) // recursively search through $parent scopes
}
});