2

在搜索了 stackoverflow 和其他网站 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/

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

4

1 回答 1

2

在调试问题时我发现,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="your_name_0"但在表单集合中,它{{content.uniqueId}}与插值指令一起显示。

似乎名称没有正确插值。

然后发现AngularJS 的问题,“您不能动态设置名称属性以进行表单验证。”

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

& 如果你想在里面工作ng-repeat,那么你应该总是使用嵌套ng-form。内部的成员ng-repeat将有自己的表单,并且使用该内部表单您可以处理您的验证。参考链接

代码更改

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>是为模板添加的,并在内部表单的基础上处理了验证。

这是你的工作小提琴

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

于 2015-01-26T08:47:15.397 回答