web-dev-qa-db-ja.com

動的フォーム入力フィールドを生成し、フィールドデータを配列で収集する

私はこの小さな仕事に行き詰まっています。フォームの「追加」ボタンをクリックして、フォーム入力フィールドを動的に生成する必要があります。フォームはDBテーブルスキーマを作成することになっています。したがって、すべての入力フィールドはDBテーブルのフィールド名です。

フィールドを動的に生成することはできますが、実際のデータの収集に問題があります。

<form ng-controller="NewTableCtrl" ng-submit="submitTable()">
  <input type='text' ng-model='table.title' placeholder='Title:'>
  <input ng-repeat="field in fields" type='text' ng-model='table.fields' placeholder='Field:'>
  <div>
    <button type='submit'>Submit</button>
    <button ng-click="addFormField()">Add</button>
  </div>
</form>

..そしてコントローラ

.controller('NewTableCtrl', function($scope) {
  $scope.fields = [];
  $scope.table = {};

  $scope.addFormField = function () {
    $scope.fields.Push({});
  }

  $scope.submitTable = function () {
    console.log($scope.table);
  }
});

シンプルに見えます。 「追加」ボタンをクリックすると、新しい入力フィールドが生成されますが、同じモデルオブジェクトを使用して(強制的に)実行されます。そして、そこに私の誤解があります。宣言したら$scope.fields = [];inコントローラーの場合、繰り返しフィールドデータは配列に格納されます。ただし、すべての繰り返し入力フィールドの入力をエコーするだけです。これが、双方向バインディングの場合の方法であることを理解しました。

私がこのように考えた理由は、繰り返し入力フィールド名がURLエンコードされたフォームデータの配列になる通常のフォーム送信との類似性によるものです。

どうすればこれを解決できますか?サーバーは、次のようなフィールドの配列を取得する必要があります:fields: [field1, field2 ...]フィールドごとに異なるスコープ変数を持つ入力フィールドを生成する必要がありますか?どうすればよいですか?

これは私が思っていたよりも複雑で、ディレクティブにする必要がありますか?はいの場合は、これを行う方法を教えてください。

ありがとう。

7
r.sendecky

現在、$scope.fieldsを反復しています。新しいフィールドを追加するときは、空のオブジェクトを$scope.fieldsにプッシュしますが、すべての入力のng-modelは$scope.table.fieldsを指します(これは、最初の入力が書き込みを行うまで存在しません-その後、文字列変数)。

この簡単な使用例では、次のことを試すことができます。

app.controller('NewTableCtrl', function($scope) {

  $scope.table = { fields: [] };

  $scope.addFormField = function() {
    $scope.table.fields.Push('');
  }

  $scope.submitTable = function() {
    console.log($scope.table);
  }

});

そして:

<input ng-repeat="field in table.fields track by $index" type='text' ng-model='table.fields[$index]' placeholder='Field:'>

デモhttp://plnkr.co/edit/6iZSIBa9S1G95pIMBRBu?p=preview

11
tasseKATT

これをみて

実用的なデモ

html

<body>
<div ng-app=''>
    <div ng-controller="questionCtrl">
        <div>
            <ul>
                <li ng-repeat="elemnt in questionelemnt">

                    <div>
                        <div id={{elemnt.id}} style="display:inline" >
                            <span  ng-model="elemnt.question" ng-hide="editorEnabled" ng-click="editorEnabled=true">
                                {{elemnt.question}}
                            </span>
                            <div  ng-show="editorEnabled">
                                <input  ng-model="elemnt.question" ng-show="editorEnabled" >
                                <button href="#" ng-click="editorEnabled=false">Done editing</button>
                            </div>
                        </div>
                        <div style="display:inline">
                            <span>
                                <input type="text" ng-model="elemnt.answer" placeholder="Answer" required/>
                            </span>
                        </div>

                        <span ng-hide="elemnt.length == 1">

                             <button ng-click="questionelemnt.splice($index, 1)">Remove</button>

                        </span>
                    </div>
                    <hr/>
                </li>
                <li>
                     <button ng-click="addFormField($event)">Add</button>
                </li>
            </ul>
        </div>
        <div>
            <button ng-click="showitems($event)">Submit</button>
        </div>
        <div id="displayitems" style="visibility:hidden;">
            {{questionelemnt}}
        </div>
    </div>
</div>
</body>

script

function questionCtrl($scope) {
    var counter = 0;
    $scope.questionelemnt = [{
        id: counter,
        question: 'Question-Click on me to edit!',
        answer: ''
    }];

    $scope.addFormField = function ($event) {
        counter++;
        $scope.questionelemnt.Push({
            id: counter,
            question: 'Question-Click on me to edit!',
            answer: ''
        });
        $event.preventDefault();
    }

    $scope.showitems = function ($event) {
        $('#displayitems').css('visibility', 'none');
    }
}
2

配列の代わりにハッシュマップを使用するtasseKATTsソリューションのバリエーション。これにより、クエリフィルターを作成するために、実行できるNice JSONオブジェクトを作成できます。

http://plnkr.co/edit/CArP3Lkmn7T5PEPdXgNt?p=preview

<!DOCTYPE html>
<html>

  <head>
    <script data-require="angular.js@*" data-semver="1.3.0" src="//code.angularjs.org/1.3.0/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
    <style>
      div{ margin: 1em;}
      input{margin-left:1em;}
    </style>
  </head>

  <body ng-controller="myCtrl">

    <h2>Using a filter map tied to ng-model to create a filter object</h2>

    <div ng-repeat="field in fields">
      {{field}}<input ng-model=filters[field] />
    </div>

    <hr>
    <h3>Filter</h3>
    {{filters}}

    <script>

      var app=angular.module("app",[]);

      app.controller("myCtrl",function($scope){
        $scope.filters={};
        $scope.fields=["name","address","phone","state"];
      });

      angular.bootstrap(document,["app"]);

    </script>

  </body>

</html>
0
mccainz