javascript - 创建一个可复制但不克隆的 Angularjs Web 表单

标签 javascript html angularjs angularjs-ng-repeat

我“尝试”构建一个 Angularjs Web 表单,该表单在单击“添加”按钮时复制输入字段,并在单击“关闭按钮”时删除新添加的字段,这似乎工作正常。太棒了,对吧!?

http://plnkr.co/edit/jUulJQ52m9QEZLkG086B

但是,单击“添加”按钮后创建的重复表单是彼此或原始表单的精确克隆。因此,当屏幕上有两个表单并且在表单 1 中输入数据时,该数据会在表单 2 上重复,反之亦然。

我的问题:

How do I continue down the path of having the ability to duplicate the elements, really, within the "fieldset" element of the form, but without it being cloned?

以下是我的 HTML 和 AngularJs 文件的片段。我已经为此绞尽脑汁有一段时间了,但一直在同一个地方结束......一组新的眼睛和/或任何建议都会很棒!

谢谢!

索引.html

<body>
  <div class="container-fluid">
    <div class="row">
      <div class="col-md-4"></div>
      <div class="col-md-4" ng-controller="formCtrl">
        <h1>Expense Form</h1>
        <form class="form-horizontal" id="itvExpenseForm" name="ExpenseForm" ng-repeat="field in table.fields track by $index" novalidate>
          <fieldset id="innerForm" ng-model="table.fields[$index]">
            <legend>
              <span>{{$index + 1}}.</span>
            </legend>
            <div class="form-group" ng-controller="quarterListCtrl">
              <label for="ddlQuarters" class="col-sm-4 control-label">Year Quarter:</label>
              <div class="col-sm-8">
                <select class="form-control" name="Quarters" id="ddlQuarters" ng-model="formData.quarter">
                  <option value="">---Please select---</option>
                  <option ng-repeat="q in quarters">{{q.name}}</option>
                </select>
              </div>
            </div>
            <div class="form-group">
              <label for="ddlDate" class="col-sm-4 control-label">Purchase Date:</label>
              <div class="col-sm-8">
                <input class="form-control" id="ddlDate" type="date" ng-model="formData.date" required>
              </div>
            </div>

            <div class="form-group">
              <div class="col-lg-10 col-lg-offset-2">
                <button id="removeMore" aria-hidden="false" ng-click="removeForm($index)" ng-show="table.fields.length > 1">Close</button>
                <button id="addMore" aria-hidden="true" ng-click="addNewForm()">Add</button>
              </div>
            </div>
          </fieldset>
        </form>
        <div class="form-group">
          <div class="col-lg-10 col-lg-offset-2">
            <button type="submit" class="btn btn-success" ng-click="submitForm()">Submit</button>
          </div>
        </div>
      </div>
      <div class="col-md-4"></div>
    </div>
  </div>
</body>

App.JS

    var app = angular.module('app', []);
app.controller('quarterListCtrl', function($scope, $http) {
  $scope.quarters = quarters;
});
app.controller('accountsListCtrl', function($scope, $http) {
  $scope.accounts = accounts;
});
app.controller('locationsListCtrl', function($scope, $http) {
  $scope.locations = locations;
});

app.controller('formCtrl', function($scope, $http) {
  $scope.formData = {};

  var formCount = 1;

  $scope.table = {
    fields: []
  };
  // create first form on page load
  $scope.table.fields.push(formCount);

  // adds new field to table array which adds to page
  $scope.addNewForm = function() {
    formCount++;
    $scope.table.fields.push(formCount);
  };
  // removes field from table array which removes form
  $scope.removeForm = function(myIndex) {
    if ($scope.table.fields.length > 1) {
      $scope.table.fields.splice(myIndex, 1);
      formCount;
    }
  };
});

var accounts = [{
  'name': 'Account One',
  'acct no': 123456789,
  'id': 1
}, {
  'name': 'Account Two',
  'acct no': 987654321,
  'id': 2
}];

var quarters = [{
  'name': 'Fall',
  'id': 1
}, {
  'name': 'Winter',
  'id': 2
}, {
  'name': 'Spring',
  'id': 3
}, {
  'name': 'Summer',
  'id': 4
}, ];

var locations = [{
  'name': 'Here',
  'id': 1
}, {
  'name': 'There',
  'id': 2
}, {
  'name': 'Everywhere',
  'id': 3
}];

最佳答案

如前所述,您的 formData 被数组中的所有元素引用,因此一个元素的更改会影响所有元素。

为了让事情变得更简单,您不需要 formCount。只需有一个 formData 数组并使用 angular.copy 。所以你的 Controller 变成:

app.controller('formCtrl', function ($scope, $http) {
    $scope.forms = [];

    // create first form on page load
    $scope.forms.push({});

    // adds new field to table array which adds to page
    $scope.addNewForm = function (formToCopy){
        $scope.forms.push(angular.copy(formToCopy));
    };
    // removes field from table array which removes form
    $scope.removeForm = function (formToRemove) {
        var formIndex = $scope.forms.indexOf(formToRemove);
        if (formIndex > -1) {
            $scope.forms.splice(formIndex, 1);
        }
    };
});

参见forked plunker完整的标记更改,但要点是将引用从 table.fields 更改为 forms 并将 formData 对象传递给 addNewForm removeForm。所以你的 ng-repeat 变成:

<form class="form-horizontal" name="ExpenseForm" ng-repeat="formData in forms track by $index" novalidate>

您不能在 fieldset 上使用 ng-model,因此这不会执行任何操作:

<fieldset id="innerForm" ng-model="table.fields[$index]">

此外,我会避免在重复的元素上使用 id 属性,否则页面上会出现多个具有相同 id 的元素。您可以选择动态 id,例如 id="innerForm-{{$index}}",但在本例中确实没有必要。

关于javascript - 创建一个可复制但不克隆的 Angularjs Web 表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34645247/

相关文章:

javascript - ng-class 完美地应用第一类,但第二类不阅读 css 规则

javascript - amCharts 不平衡

javascript - 纯 JS 自动幻灯片

html - 具有多列的 Magento 页脚

html - 如何在没有内容的容器上使用背景图像?

javascript - 在 Factory 中设置局部变量作为 Ajax 调用的结果

javascript - Node JS : Convert retrieved data from DB as JSON to Plain text

javascript - 如何在 Angular/Spring Boot 应用程序中的服务器端接收表单数据?

javascript - 如何在 Javascript 中动态设置在 Chrome 中显示的函数/对象名称

android - Tomcat 和 Android Webview 的 CORS 问题