【问题标题】:Generate dynamic form input fields and collect field data in an array生成动态表单输入字段并在数组中收集字段数据
【发布时间】:2014-04-30 14:24:34
【问题描述】:

我被这个小任务困住了。 我需要通过单击表单上的“添加”按钮来动态生成表单输入字段。 该表单应该创建数据库表模式。所以每个输入字段都是一个数据库表字段名。

我可以动态生成字段,但无法收集实际数据。

<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 = [];,那么重复的字段数据只会进入数组。但它只是在每个重复输入字段中回显输入。我现在明白这就是双向绑定的方式。

我这样想的原因是类似于普通的表单提交,其中重复的输入字段名称变成了 URL 编码表单数据中的一个数组。

那么我该如何解决呢?服务器需要获取这样的字段数组:fields: [field1, field2 ...] 我是否需要为每个字段生成具有不同范围变量的输入字段?我该怎么做?

这比我想象的更复杂吗?它需要一个指令吗?如果是,请告诉我如何执行此操作。

谢谢。

【问题讨论】:

    标签: angularjs angularjs-directive angularjs-ng-repeat


    【解决方案1】:

    现在你正在迭代$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

    【讨论】:

    • 谢谢。这很好。我也了解了track by。出于性能原因,始终使用track by 是否有益?
    • 不客气 :) 在更复杂的情况下是的 (bennadel.com/blog/…)。在这种情况下,可以有多个具有相同字符串值的字段,否则您会得到:'不允许在转发器中重复。使用 'track by' 表达式来指定唯一键。'
    • 我知道这是一个旧线程,仍然需要问一些问题。如何以使用上述代码创建的表单显示数据?任何帮助将不胜感激
    • @Vishal_Kotecha 你是这个意思吗? plnkr.co/edit/F1OhZ8qcwLA75rQOoaWO?p=preview
    • @tasseKATT 感谢您的及时回复。很抱歉第一次不清楚。实际上我有 json,我想将该 json 转换为带有数据的表单。例如我有代表文本框及其值的 json。现在我需要将其转换为带有值的文本框。
    【解决方案2】:

    看看这个

    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>
    

    脚本

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

    【讨论】:

      【解决方案3】:

      使用哈希图而不是数组的 tasseKATTs 解决方案的变体。 这让我可以拥有一个很好的 JSON 对象,我可以直接 for-in 来构建我的查询过滤器。

      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>
      

      【讨论】:

        猜你喜欢
        • 2021-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-17
        • 1970-01-01
        • 2012-07-19
        • 1970-01-01
        • 2018-10-05
        相关资源
        最近更新 更多