2014-04-30 3 views
7

Ich bin mit dieser kleinen Aufgabe fest. Ich muss Formular Eingabefelder dynamisch generieren, indem Sie auf "Hinzufügen" im Formular klicken. Das Formular soll DB-Tabellenschema erstellen. Jedes Eingabefeld ist also ein DB-Tabellenfeldname.Erzeuge dynamische Form Eingabefelder und sammle Felddaten in einem Array

Ich bin OK die Felder dynamisch zu erzeugen, habe aber Probleme mit den aktuellen Daten zu sammeln.

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

.. und die Steuerung

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

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

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

Sieht einfach. Wenn ich auf die Schaltfläche "Hinzufügen" klicke, wird das neue Eingabefeld generiert, jedoch mit dem gleichen Modellobjekt (offensichtlich). Und da liegt mein Missverständnis. Ich dachte, dass, wenn ich $scope.fields = []; in der Steuerung erkläre, dann wiederholende Felddaten gerade in das Array gehen. Aber es gibt nur die Eingabe in jedem sich wiederholenden Eingabefeld wieder. Ich verstehe jetzt, dass es so ist, wie es mit Zwei-Wege-Bindung sein soll.

Der Grund ich so gedacht ist, durch die Analogie mit einer gewöhnlichen Form, wo die Vorlage wiederholenden Eingabefeldnamen werden ein Array in den URL-codierten Form-Daten.

Also, wie löse ich das? Der Server muss ein Feld mit folgenden Feldern erhalten: fields: [field1, field2 ...] Muss ich für jedes Feld Eingabefelder mit verschiedenen Bereichsvariablen generieren? Wie mache ich das?

Ist das komplexere dann dachte ich, und es muss eine Richtlinie sein? Wenn ja, zeig mir bitte, wie das geht.

Danke.

Antwort

11

Im Moment iterieren Sie $scope.fields. Wenn Sie ein neues Feld hinzufügen, drücken Sie ein leeres Objekt in $scope.fields, aber das ng-Modell jeder Eingabe zeigt auf $scope.table.fields (was nicht existiert, bis die erste Eingabe in es schreibt - dann wird es eine String-Variable enthalten).

Für diesen einfachen Anwendungsfall könnten Sie versuchen:

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

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

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

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

}); 

Und:

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

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

+0

Danke. Das ist nett. Ich habe auch etwas über 'track by' gelernt. Ist es sinnvoll, aus Performance-Gründen immer 'track by' zu verwenden? –

+0

Gern geschehen :) In komplexeren Situationen ja (http://www.bennadel.com/blog/2556-using-track-by-with-ngrpeat-in-angularjs-1-2.htm). In diesem Fall ist es möglich, mehrere Felder mit demselben Zeichenfolgenwert zu verwenden. Andernfalls würden Sie Folgendes erhalten: "Duplikate in einem Repeater sind nicht zulässig. Verwenden Sie den Ausdruck "Track by", um eindeutige Schlüssel anzugeben. ' – tasseKATT

+0

Ich weiß, das ist ein alter Thread, muss noch etwas fragen. Wie zeige ich Daten in dem Formular an, das mit dem obigen Code erstellt wurde? Jede Hilfe würde geschätzt werden –

2

Werfen Sie einen Blick auf diese

Working Demo

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> 

Skript

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'); 
    } 
} 
0

Variation von tasseKATTs Lösung eine hashmap anstelle eines Arrays verwenden. Dies ermöglicht mir, ein nettes JSON-Objekt zu haben, über das ich nur for-in gehen kann, um meinen Abfragefilter zu erstellen.

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

<!DOCTYPE html> 
<html> 

    <head> 
    <script data-require="[email protected]*" 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>