ngModel。$解析器指令
我要动态地添加指令,以形成元素不工作(输入,选择,文本区域...)
<div ng-app="app" ng-controller="ctrl">
<form form-validator>
<input type="text" ng-model="model1">
<input type="text" ng-model="model2">
<input type="text" ng-model="model3">
<textarea ng-model="model4"></textarea>
<select>
<option ng-model="model5" value="1">Name</option>
</select>
</form>
</div>
指令上述
var app=angular.module('app',[])
.controller('ctrl',function($scope){
})
.directive('formValidator',function($compile){
return{
restrict: 'A',
link: function(scope, elem, attrs){
//is it possible to do this with one line of code?
elem.find('input').attr('validate-field','');
elem.find('select').attr('validate-field','');
elem.find('textarea').attr('validate-field','');
$compile(elem.contents())(scope);
}
}
})
.directive('validateField',function(){
return{
restrict: 'A',
require:['^ngModel'],
link: function(scope, element, attr, ctrls){
var valid = false;
var ngModel = ctrls[0];
alert('before validation');
ngModel.$parsers.unshift(function (value){
alert('validating');
valid = validator(value);
ngModel.$setValidity('required', valid, ctrls);
return valid ? value : undefined;
});
}
}
});
的代码能够添加validate-field
属性,以形成元素:
<input type="text" ng-model="model1" validate-field>
问题是ngModel.$parsers.unshift
未被调用,alert('before validation');
被调用,但alert('validating');
未被调用。
我错过了什么?
目前发生了什么是你formValidator
指令链接函数正在评估所有子代validateField
指令得到编译。因为link: function(){ .. }
函数被视为与postLink函数相同,在所有子项目链接就绪之后被调用。你的情况也是如此。
所以,我会说,确实要调用链接函数,以确保它会在指令编译前添加validate-fields
。为此,您需要使用preLink
函数。
.directive('formValidator', function($compile) {
return {
restrict: 'A',
link: {
pre: function(scope, elem, attrs) {
elem.find('input').attr('validate-field', '');
elem.find('select').attr('validate-field', '');
elem.find('textarea').attr('validate-field', '');
$compile(elem.contents())(scope);
}
}
}
})
更多更好的版本将编译父指令只有一次
.directive('formValidator', function($compile) {
return {
restrict: 'A',
compile: function(elem, attrs) {
elem.find('input').attr('validate-field', '');
elem.find('select').attr('validate-field', '');
elem.find('textarea').attr('validate-field', '');
//removed to avoid infinite directive compile
elem.removeAttr('form-validator');
var linkFn = $compile(elem);
return function(scope, element, attr) {
linkFn(scope);
}
}
}
})
因为我一直在努力从很长一段时间.. –
也许,你想使用$formatters
。
plunker上的示例。
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<script data-require="[email protected]" data-semver="1.4.7" src="https://code.angularjs.org/1.4.7/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<h1>Angular Directive</h1>
<div ng-app="app" ng-controller="ctrl">
<form form-validator="">
<input type="text" ng-model="model1" />
<input type="text" ng-model="model2" />
<input type="text" ng-model="model3" />
<textarea ng-model="model4"></textarea>
<select ng-model="model5">
<option value="1">Name</option>
</select>
<button ng-click="model1='A'"> set model 1 value A</button>
</form>
</div>
<script>
var app=angular.module('app',[])
.controller('ctrl',function($scope){
})
.directive('formValidator',function($compile){
return{
restrict: 'A',
priority:10000,
link: function(scope, elem, attrs){
//is it possible to do this with one line of code?
elem.find('input').attr('validate-field','');
elem.find('select').attr('validate-field','');
elem.find('textarea').attr('validate-field','');
$compile(elem.contents())(scope);
}
}
})
.directive('validateField',function(){
return{
restrict: 'A',
require:'ngModel',
link: function(scope, element, attr, ngModel){
var valid = false;
console.log('before validation',ngModel);
ngModel.$formatters.unshift(function (value){
console.log('validating');
//valid = validator(value);
ngModel.$setValidity('required', valid, ngModel);
return valid ? value : undefined;
});
ngModel.$parsers.unshift(function (value){
console.log('$parsers');
valid = true;
ngModel.$setValidity('required', valid, ngModel);
return valid ? value : undefined;
});
}
}
});
</script>
</body>
</html>
感谢您为您+1回应 – Digitlimit
你应该使用'要求:[ 'ngModel']'里面你'validateField'指令,使其工作..这样的'ngModelController'将可使用。 –
@Pankaj Parkar仍然不工作时,需要:['^ ngModel'],'是否加入 – Digitlimit
请你能告诉我一个你的意思吗? – Digitlimit