2014-09-03 59 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