Angular 带有动态生成的输入字段的指令无法显示验证
Angular Directive with dynamically generated input fields not able to display validation
在搜索 Whosebug 和其他站点 3 天之后,我发现自己回到了原点。
我的任务:我需要验证动态生成的表单域。
HTML:
<form name="myForm">
<form-field content="field" model="output[field.uniqueId]" ng-repeat="field in formFields"></form-field>
</form>
控制器:
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={};
}
指令:
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:'=?'
}
};
});
显然存在一些范围问题,因为我无法访问指令外的表单字段,也无法访问指令内的表单名称。我也知道 $scope.myForm.name 属性 不能是 angular 绑定表达式,但我不确定如何重写它以使其工作。
这是 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}}
与插值指令。
名称似乎没有正确插入。
然后找到issue和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)
& 如果你想在 ng-repeat
中使用它们,那么你应该始终使用嵌套 ng-form
。 ng-repeat
内的成员将拥有自己的表单,使用该内部表单您可以处理验证。 Link For Reference
代码更改
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>'
};
只有我更改了模板html,基本上为模板添加了<ng-form></ng-form>
并在内部形式的基础上处理了验证。
这是你的Working Fiddle
希望这已经清除了您的理解。谢谢。
在搜索 Whosebug 和其他站点 3 天之后,我发现自己回到了原点。
我的任务:我需要验证动态生成的表单域。
HTML:
<form name="myForm">
<form-field content="field" model="output[field.uniqueId]" ng-repeat="field in formFields"></form-field>
</form>
控制器:
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={};
}
指令:
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:'=?'
}
};
});
显然存在一些范围问题,因为我无法访问指令外的表单字段,也无法访问指令内的表单名称。我也知道 $scope.myForm.name 属性 不能是 angular 绑定表达式,但我不确定如何重写它以使其工作。
这是 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}}
与插值指令。
名称似乎没有正确插入。
然后找到issue和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)
& 如果你想在 ng-repeat
中使用它们,那么你应该始终使用嵌套 ng-form
。 ng-repeat
内的成员将拥有自己的表单,使用该内部表单您可以处理验证。 Link For Reference
代码更改
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>'
};
只有我更改了模板html,基本上为模板添加了<ng-form></ng-form>
并在内部形式的基础上处理了验证。
这是你的Working Fiddle
希望这已经清除了您的理解。谢谢。