带有动态生成的输入字段的 Angular 指令无法显示验证 [英] Angular Directive with dynamically generated input fields not able to display validation
问题描述
在 3 天的时间里搜索 stackoverflow 和其他网站后,我发现自己又回到了第一站.
我的任务:我需要验证动态生成的表单字段.
HTML:
控制器:
var myApp = angular.module('myApp',[]);函数 MyCtrl($scope) {$scope.formFields = [{"fieldName": "你的名字","uniqueId": "your_name_0","fieldType": "文本","isMandatory": 真},{"fieldName": "描述","uniqueId": "description_1","fieldType": "textarea","isMandatory": 真,}];$scope.output={};}
指令:
myApp.directive("formField",function($compile){var 模板 = {textTemplate:'<div class="form-group"><label for="{{content.uniqueId}}" >{{content.fieldName}}</label><span ng-show="content.isMandatory" class="sub_reqText">*</span><span ng-show="form.content.fieldName.$invalid">请检查此字段.<;/span><input type="text" ng-model="model" name="{{content.uniqueId}}" class="form-control" ng-required="content.isMandatory" id="{{content.uniqueId}}"/></div><br>',textareaTemplate:'<div class="form-group"><label for="{{content.uniqueId}}" >{{content.fieldName}}</label><span ng-show="content.isMandatory" class="sub_reqText">*</span><span ng-show="form.content.fieldName.$invalid">请检查此字段.</span><textarea ng-model="model" name="{{content.uniqueId}}" id="{{content.uniqueId}}" class="form-control" ng-required="content.isMandatory"></textarea>
'};var getTemplate = 函数(内容,属性){var 模板 = {};模板 = 模板[content.fieldType+"模板"];if(typeof template != 'undefined' && 模板 != null) {返回模板;}别的 {返回 '';}};var 链接器 = 函数(作用域、元素、属性){element.html(getTemplate(scope.content, attrs)).show();$compile(element.contents())(scope);}返回 {限制:E",替换:真,链接:链接器,范围:{内容:'=',型号:'=?'}};});
显然存在一些范围问题,因为我无法访问指令外的表单字段,也无法访问指令内的表单名称.我也知道 $scope.myForm.name 属性不能是角度绑定表达式,但我不确定如何重写它以使其工作.
这是jsfiddle:http://jsfiddle.net/scheedalla/57tt04ch/>
任何指导都会非常有用,谢谢!
在调试问题时发现,name 属性没有正确编译为表单.它在名称中显示 {{content.uniqueId}}
但实际上它在 UI 上正确呈现.
例如.对于以下 html.
<input type="text" ng-model="model" name="{{content.uniqueId}}" class="form-control"ng-required="content.isMandatory" id="{{content.uniqueId}}"/>
name 呈现为 name="your_name_0"
但在表单集合中它显示 {{content.uniqueId}}
和插值指令.
似乎名称没有正确插入.
然后发现问题 AngularJS,您无法设置名称动态属性用于表单验证."
<块引用>注意:上述问题已在 Angular 1.3.(name属性正确插入)
&如果你想在 ng-repeat
中使用它们,那么你应该总是使用嵌套的 ng-form
.ng-repeat
中的成员将拥有自己的表单,并且使用该内部表单您可以处理您的验证.参考链接
代码更改
var 模板 = {textTemplate: '<ng-form name="form">'+''+'<label for="{{content.uniqueId}}">{{content.fieldName}}</label>'+'<span ng-show="content.isMandatory" class="sub_reqText">*</span>'+''+'请检查此字段.'+'</span>'+'<input type="text" ng-model="model1" name="input" class="form-control" ng-required="content.isMandatory" id="{{content.uniqueId}}"/>'+'</div>'+'</ng-form>'+'
',textareaTemplate: '<ng-form name="form">'+''+'<label for="{{content.uniqueId}}">{{content.fieldName}}</label>'+'<span ng-show="content.isMandatory" class="sub_reqText">*</span>'+'<span ng-show="form.textarea.$invalid">请检查此字段.</span>'+'<textarea ng-model="model" name="textarea" id="{{content.uniqueId}}" class="form-control" ng-required="content.isMandatory"></textarea>'+'</div>'+'</ng-form>'};只有我更改了模板html,基本上为模板添加了<ng-form></ng-form>
,并在内部表单的基础上处理了验证.
这是您的工作小提琴
希望这已经让您明白了.谢谢.
After 3 days of scouring stackoverflow and other sites, I have found myself back at square one.
My task: I need to validate dynamically generated form fields.
The HTML:
<form name="myForm">
<form-field content="field" model="output[field.uniqueId]" ng-repeat="field in formFields"></form-field>
</form>
The controller:
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.formFields = [
{
"fieldName": "Your Name",
"uniqueId": "your_name_0",
"fieldType": "text",
"isMandatory": true
},
{
"fieldName": "Description",
"uniqueId": "description_1",
"fieldType": "textarea",
"isMandatory": true,
}
];
$scope.output={};
}
The directive:
myApp.directive("formField",function($compile){
var templates = {
textTemplate:'<div class="form-group"><label for="{{content.uniqueId}}" >{{content.fieldName}}</label> <span ng-show="content.isMandatory" class="sub_reqText">*</span><span ng-show="form.content.fieldName.$invalid">Please check this field.</span><input type="text" ng-model="model" name="{{content.uniqueId}}" class="form-control" ng-required="content.isMandatory" id="{{content.uniqueId}}"/> </div><br>',
textareaTemplate:'<div class="form-group"><label for="{{content.uniqueId}}" >{{content.fieldName}}</label> <span ng-show="content.isMandatory" class="sub_reqText">*</span> <span ng-show="form.content.fieldName.$invalid">Please check this field.</span> <textarea ng-model="model" name="{{content.uniqueId}}" id="{{content.uniqueId}}" class="form-control" ng-required="content.isMandatory"></textarea> </div>'
};
var getTemplate = function(content, attrs){
var template = {};
template = templates[content.fieldType+"Template"];
if(typeof template != 'undefined' && template != null) {
return template;
}
else {
return '';
}
};
var linker = function(scope, element, attrs){
element.html(getTemplate(scope.content, attrs)).show();
$compile(element.contents())(scope);
}
return {
restrict:"E",
replace:true,
link:linker,
scope:{
content:'=',
model:'=?'
}
};
});
There is clearly some scope issue because I cannot access the form fields outside of the directive and I cannot access the form name inside the directive. I also know $scope.myForm.name property cannot be an angular binding expression but I am not sure how to rewrite it so that it works.
This is the jsfiddle: http://jsfiddle.net/scheedalla/57tt04ch/
Any guidance will be very useful, thank you!
解决方案 While debugging the problem I found that, the name attribute is not properly compiled for form. It was showing {{content.uniqueId}}
in name but actually it rendered properly on UI.
Eg.
For below html.
<input type="text" ng-model="model" name="{{content.uniqueId}}" class="form-control"
ng-required="content.isMandatory" id="{{content.uniqueId}}"/>
name rendered as name="your_name_0"
but in form collection it was showing {{content.uniqueId}}
with the interpolation directive.
Seems like name is not interpoluted properly.
Then found issue with AngularJS, "You can't set name attribute dynamically for form validation."
Note: Above mentioned issue has been fixed in Angular 1.3.(name
attributes interpolates properly)
& If you wanted to work them inside ng-repeat
, then you should always use nested ng-form
. Members inside ng-repeat
will have their own form, and using that inner form you can handle your validation. Link For Reference
CODE CHANGE
var templates = {
textTemplate: '<ng-form name="form">'+
'<div class="form-group">'+
'<label for="{{content.uniqueId}}">{{content.fieldName}}</label> '+
'<span ng-show="content.isMandatory" class="sub_reqText">*</span>'+
'<span ng-show="form.input.$invalid">'+
'Please check this field.'+
'</span>'+
'<input type="text" ng-model="model1" name="input" class="form-control" ng-required="content.isMandatory" id="{{content.uniqueId}}" /> '+
'</div>'+
'</ng-form>'+
'<br>',
textareaTemplate: '<ng-form name="form">'+
'<div class="form-group">'+
'<label for="{{content.uniqueId}}">{{content.fieldName}}</label>'+
'<span ng-show="content.isMandatory" class="sub_reqText">*</span> '+
'<span ng-show="form.textarea.$invalid">Please check this field.</span>'+
'<textarea ng-model="model" name="textarea" id="{{content.uniqueId}}" class="form-control" ng-required="content.isMandatory"></textarea>'+
'</div>'+
'</ng-form>'
};
Only i changed the template html, basically added <ng-form></ng-form>
for templates and handled the validation on basis it in inner form.
Here is your Working Fiddle
Hope this have cleared your understanding. Thanks.
这篇关于带有动态生成的输入字段的 Angular 指令无法显示验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文