2013-04-05 21 views
28

に登録されていないI持ってAngularJSで、次の静的形式:AngularJS:フィールドを動的に追加はFormController

<form name="myForm" class="form-horizontal"> 

    <label>First Name:</label> 
    <input type="text" name="first_name" ng-model="entity.first_name"> 

    <label>Last Name:</label> 
    <input type="text" name="last_name" ng-model="entity.last_name"> 

</form> 

角度が私のためにFormControllerを作成し、(フォーム名の下に)スコープにそれを公開しています。つまり、次のようなプロパティにアクセスできます。

$scope.myForm.first_name.$error 
$scope.myForm.last_name.$invalid 
... 

これは非常に便利です!

しかし、私の場合は私が動的にフォームを構築、ディレクティブを使用しています:私はいくつかをフェッチした後(

<form name="myForm" class="form-horizontal"> 

    <field which="first_name"></field> 
    <field which="last_name"></field> 

</form> 

<field>ディレクティブはしばらく後まで、実際の<input>要素に解決されません。サーバーからのデータ、指示文のリンクなど)。ダイナミックフィールドがFormControllerに登録しませんでしたかのように

問題ここでは、何のフィールドプロパティは、フォームコントローラ上で定義されていないということです。

// The following properties are UNDEFINED (but $scope.myForm exists) 
$scope.myForm.first_name 
$scope.myForm.last_name 

任意のアイデアなぜですか?任意のソリューション/回避策?

あなたはこのjsFiddleでコード全体を参照することができます
http://jsfiddle.net/vincedo/3wcYV/

+0

を動作させるために少しハックとフィドルがあるを表示することができますか?私はこれが範囲の問題だと思う。 – Intelekshual

+0

これを参照してくださいjsFiddle:http://jsfiddle.net/vincedo/3wcYV/ – AngularChef

答えて

24

アップデートを2015年7月31日これは、1.3以降に修正されました、こちらをご覧ください:https://github.com/angular/angular.js/issues/1404#issuecomment-125805732

オリジナル回答 これを残念ながら、現時点でAngularJSの短期間の来航です。 Angularのフォーム検証は、動的に名前が付けられたフィールドでは機能しません。あなたが起こっているのを正確に知るために、あなたのHTMLの一番下に以下を追加することができます:あなたが見ることができるように

<pre>{{myForm|json}}</pre> 

、角度は右の動的入力名を取得されていません。現在、ネストされたフォームを使用して厄介な作業をする作業はありますが、動作します(少し余分な作業で)親フォームを問題なく送信します。

希望の場合は、問題の詳細をドラムアップしてください:GitHub Issue - dynamic element validation。いずれにせよ、ここでのコードは次のとおりです。

http://jsfiddle.net/langdonx/6H8Xx/2/

HTML:

<div data-ng-app> 
    <div data-ng-controller="MyController"> 
     <form id="my_form" name="my_form" action="/echo/jsonp/" method="get"> 
      <div data-ng-repeat="field in form.data.fields"> 
       <ng-form name="form"> 
        <label for="{{ field.name }}">{{ field.label }}:</label> 
        <input type="text" id="{{ field.name }}" name="{{field.name}}" data-ng-model="field.data" required> 
        <div class="validation_error" data-ng-show="form['\{\{field.name\}\}'].$error.required">Can't be empty.</div> 

       </ng-form> 
      </div> 
      <input type="submit" /> 
     </form> 
    </div> 
</div> 

はJavaScript:

MyController.$inject = ["$scope"]; 

function MyController($scope) { 
    $scope.form = {}; 
    $scope.form.data = {}; 
    $scope.form.data.fields = [] 

    var f1 = { 
     "name": "input_1", 
     "label": "My Label 1", 
     "data": "" 
    }; 
    var f2 = { 
     "name": "input_2", 
     "label": "My Label 2", 
     "data": "" 
    }; 

    $scope.form.data.fields.push(f1); 
    $scope.form.data.fields.push(f2); 
} 
+1

説明とその回避策をありがとうございました。これを読んでいる人には、私はフォームマークアップのサーバー側を生成することになりました。これにはいくつかの利点があります:1)上記のダイナミックフィールドの問題を回避する。 2)は私によく知られているフォームライブラリを使用できます(私の場合は[WTForms](http://wtforms.simplecodes.com/))。 3)フォーム定義を表すJavascriptオブジェクトの作成を回避する。 4)モデルとフォーム間の緊密な統合(すべてがサーバー側のコードで定義されているため) – AngularChef

2

私は同様の問題に自分自身を走ったと私はそれを回避するためにやったことでしたテンプレートの$ compileを呼び出す前にフィールドの名前を配置します。単純なstring.replaceがトリックを行いました。それから私はhttpを介してフィールドテンプレートを取得していて、テンプレートテキストへのアクセス権を持っていたので、これは再び可能でした。

更新:あなたは私達にあなたの `field`ディレクティブのコードをここにあなたの例では、

app.directive('field', function($compile) { 
    var linker= function(scope, element){ 

    var template = '<input type="text" name="{{fname}}" ng-model="model">' 
    .replace('{{fname}}', scope.fname); 
     element.html(template) 
     $compile(element.contents())(scope) 
    } 
    return { 
    restrict: 'E', 
    scope: { 
     fname: '=', 
     model: '=' 
    }, 

    replace: true, 
     link: linker 
    }; 
}); 

http://jsfiddle.net/2Ljgfsg9/4/

関連する問題