带有动态生成的输入字段的 Angular 指令无法显示验证 [英] Angular Directive with dynamically generated input fields not able to display validation

查看:18
本文介绍了带有动态生成的输入字段的 Angular 指令无法显示验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 3 天的时间里搜索 stackoverflow 和其他网站后,我发现自己又回到了第一站.

我的任务:我需要验证动态生成的表单字段.

HTML:

 
<form-field content="field" model="output[field.uniqueId]" ng-repeat="formFields 中的字段"></form-field></表单>

控制器:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆