具有动态生成的输入字段的Angular Directive无法显示验证

时间:2015-01-23 20:23:21

标签: angularjs validation angularjs-directive angularjs-scope angular-template

经过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属性不能是一个有角度的绑定表达式,但我不知道如何重写它以便它可以工作。

这是jsfiddle:http://jsfiddle.net/scheedalla/57tt04ch/

任何指导都会非常有用,谢谢!

1 个答案:

答案 0 :(得分:2)

在调试问题时我发现,没有为表单正确编译name属性。它在名称中显示{{content.uniqueId}},但实际上它在UI上正确呈现。

EG。 对于html。

<input type="text" ng-model="model" name="{{content.uniqueId}}" class="form-control" 
ng-required="content.isMandatory" id="{{content.uniqueId}}"/>

呈现为name="your_name_0"的名称,但在表单集合中,它使用插值指令显示{{content.uniqueId}}

似乎名称没有正确插入。

然后使用AngularJS找到issue,&#34;您无法动态设置名称属性以进行表单验证。&#34;

  

注意:上述问题已在Angular 1.3中修复。(名称   属性正确插值)

&安培;如果您想在ng-repeat中使用它们,那么您应该始终使用嵌套的ng-formng-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

希望这已经清除了你的理解。感谢。