2014-09-03 51 views
2

我想验证使用指令生成的动态表单输入并隔离范围。在指令之外,我有主窗体,在ng-repeat内部,我试图使用ng-form,但它不会显示错误消息。最初,我在ng-repeat上使用了ng-form,但认为这是行不通的,因为它超出了指令的范围,所以将它放在指令的父div上,但仍然不显示对无效电子邮件的验证。AngularJS表单验证动态生成的输入指令不与ngForm工作

形式NG-重复和现场指导

<form name="mainForm" 
     role="form" 
     ng-controller="WizardFormController as wizFormCtrl" 
     ng-submit="submit(mainForm.$valid)" 
     novalidate> 

     <div ng-repeat="field in panel.form_fields"> 

      <form-field field="field" 
         model="models[field.field_name]" ng-form="subForm"> 
      </form-field> 

     </div> 

     <div class="form-group clearfix"> 
     <button class="btn btn-primary pull-right" 
       ng-click="update(models)" 
       ng-disabled="mainForm.$invalid">Save Progress</button> 

     </div> 

</form> 

表格字段指令

<div class="form-group" ng-form="subForm"> 

    <label for="{{field.field_name}}">{{field.field_label}}</label> 

    <input type="text" 
     class="form-control" 
     id="{{field.field_id}}" 
     name="{{field.field_name}}" 
     ng-model="model"> 

    <div ng-show="subForm[field.field_name].$dirty && 
       subForm[field.field_name].$invalid">Invalid: 

    <span ng-show="subForm[field.field_name].$error.email">This is not a valid email.</span> 
    </div> 

</div> 

看起来像它应该工作,寻找在生成的标记指示场NG-有效:

<div class="form-group ng-scope ng-dirty ng-valid-required ng-valid ng-valid-email" 
    ng-form="subForm"> 

它是我如何访问子表单:

subForm[field.field_name].$dirty 

UPDATE 我发现周围的工作,这和下面回答了这个问题,看here

+0

你可以发布你的指令JS代码以及演示fiddler/plnkr吗? – Beyers 2014-09-03 21:51:02

回答

7

这个问题的解决方案显然是在工作中,并且一直是2年以上的问题。将您的投票加入GitHub!最简单的解决方案,可以说是最好的解决方案可以找到here与信贷Thinkscape,我已经复制下面。

angular.module('interpol', []) 

    .config(function($provide) { 

    $provide.decorator('ngModelDirective', function($delegate) { 
     var ngModel = $delegate[0], controller = ngModel.controller; 
     ngModel.controller = ['$scope', '$element', '$attrs', '$injector', function(scope, element, attrs, $injector) { 
     var $interpolate = $injector.get('$interpolate'); 
     attrs.$set('name', $interpolate(attrs.name || '')(scope)); 
     $injector.invoke(controller, this, { 
      '$scope': scope, 
      '$element': element, 
      '$attrs': attrs 
     }); 
     }]; 
     return $delegate; 
    }); 

    $provide.decorator('formDirective', function($delegate) { 
     var form = $delegate[0], controller = form.controller; 
     form.controller = ['$scope', '$element', '$attrs', '$injector', function(scope, element, attrs, $injector) { 
     var $interpolate = $injector.get('$interpolate'); 
     attrs.$set('name', $interpolate(attrs.name || attrs.ngForm || '')(scope)); 
     $injector.invoke(controller, this, { 
      '$scope': scope, 
      '$element': element, 
      '$attrs': attrs 
     }); 
     }]; 
     return $delegate; 
    }); 
    }) 

    .run(function($rootScope) { 
    $rootScope.models = [{ 
     value: 'foo' 
    },{ 
     value: 'bar' 
    },{ 
     value: 'baz' 
    }]; 
}); 

我刚把它放进去,标记为依赖项,并且我的问题中的表单工作。

干杯

+2

虽然这实际上是如何运作的,但对于AngularJS来说我太新了。任何有兴趣提供上述解决方案的高级描述的人员? – mtpultz 2014-09-03 20:35:28

+0

看起来已经写出这个答案,因为这个答案写成:[link](https://github.com/angular/angular.js/issues/1404#issuecomment-125805732),你现在可以完成动态表单验证而无需解决方法 – Mathew 2016-09-20 01:46:51

0

以此为表单域指令:

<div class="form-group" ng-form="subForm"> 

    <label for="{{field.field_name}}">{{field.field_label}}</label> 

    <input type="email" 
     class="form-control" 
     id="formid" 
     name="formname" 
     ng-model="model"> 

    <div ng-show="subForm.formname.$dirty && 
       subForm.formname.$invalid">Invalid: 

    <span ng-show="subForm.formname.$error.email">This is not a valid email.</span> 
    </div> 

</div> 

NG-形式本身处理的字段名。你不能像这样放name="{{field.field_name}}"

+0

嗨,如果我不能避免这种情况,因为我们使用表单字段指令和json生成大量表单,所以唯一的硬编码位是类型,并且我们提供所有不同的html输入类型和选择为模板。是否有另一种方法可能不会使用ngForm,这只是我通过AngularJS文档和一些教程找到的一种方式。 – mtpultz 2014-09-03 18:52:33

+0

我不认为有这个选择。动态生成的表单字段只能通过这个来验证。 – 2014-09-03 19:00:03

+0

它确实在父窗体中进行了验证,而不是在特定的输入上允许我显示输入错误。我会继续挖掘,看看是否有某种解决方案。谢谢 – mtpultz 2014-09-03 19:05:47

相关问题