Javascript 对动态生成的输入指令进行AngularJS表单验证,该指令不适用于ngForm

Javascript 对动态生成的输入指令进行AngularJS表单验证,该指令不适用于ngForm,javascript,jquery,angularjs,forms,validation,Javascript,Jquery,Angularjs,Forms,Validation,我试图验证使用指令生成的动态表单输入,并隔离作用域。在指令外部,我得到了主窗体,在ng repeat内部,我尝试使用ng窗体,但它从未显示错误消息。最初,我在ng repeat上使用了ng表单,但我认为这不起作用,因为它超出了指令的范围,所以将它放在指令的父div上,但仍然没有显示对无效电子邮件的验证 带有ng repeat和field指令的表单 <form name="mainForm" role="form" ng-controller="WizardFor

我试图验证使用指令生成的动态表单输入,并隔离作用域。在指令外部,我得到了主窗体,在ng repeat内部,我尝试使用ng窗体,但它从未显示错误消息。最初,我在ng repeat上使用了ng表单,但我认为这不起作用,因为它超出了指令的范围,所以将它放在指令的父div上,但仍然没有显示对无效电子邮件的验证

带有ng repeat和field指令的表单

<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="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>

{{field.field_label}
无效:
这不是一封有效的电子邮件。

ng表单本身处理字段名。你不能像这样把
name=“{{field.field\u name}}”
放进去。

这个问题的解决方案显然正在酝酿之中,已经存在了2年多了。加上你的投票!要实现的最简单的解决方案,也可以说是最好的解决方案,可以通过credit to找到,我在下面复制了它

  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'
    }];
});
我只是把它放进去,把它标记为一个依赖项,我问题中的表单就可以工作了


干杯

Hi,如果我无法避免这一点,因为我们使用表单字段指令和json生成大量表单,因此唯一的硬编码位是类型,我们提供所有不同的html输入类型并选择作为模板。有没有其他方法可以做到这一点,也许不使用ngForm,这只是我在AngularJS文档和一些教程中找到的一种方法。我认为没有其他方法可以做到这一点。动态生成的表单字段只能通过此项进行验证。它确实在父表单中正确验证,但不能在特定输入上进行验证,从而允许我显示输入错误。我会继续挖掘,看看是否有某种解决办法。感谢您将type=“email”用于验证电子邮件表单。我认为对于特定的输入字段它也能正常工作。用编辑过的代码嘿,我找到了解决办法。这一特定问题有几个不同的解决方案,在过去的两年中已经合并,可以在GitHub()上找到。访问的最简单解决方案是:。只需将其添加为依赖项,上述示例中的代码就可以正常工作。虽然这实际上是如何工作的是一个谜,但我对AngularJS太陌生了。有没有人对上述解决方案有兴趣做一个高层描述?看起来这个问题已经解决了,因为这个答案已经写好了:您现在可以完成动态表单验证,而无需解决方法扫描您发布的指令JS代码以及演示fiddler/plnkr?
subForm[field.field_name].$dirty
<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>
  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'
    }];
});