创建一个Angularjs web表单,该表单重复但没有't克隆

Create an Angularjs web form that duplicates but doesn't clone

本文关键字:表单 克隆 一个 web Angularjs 创建      更新时间:2023-09-26

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

http://plnkr.co/edit/jUulJQ52m9QEZLkG086B

但是,单击"添加"按钮后创建的重复表单是彼此或原始表单的完全克隆。因此,当屏幕上有两个表格,数据输入表格1时,它会在表格2上复制,反之亦然。

我的问题:

我该如何继续拥有这种能力在表单的"fieldset"元素中复制元素,但不进行克隆?

以下是我的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>

应用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。所以你的控制器变成了:

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对象传递给addNewFormremoveForm。所以你的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="innerForm-{{$index}}"这样的动态id,但在这种情况下确实没有必要。

所有的"ng模型"声明都链接到对象"formData"中的一个变量,例如。表格数据季度formData.date

但是您的作用域中只有一个formData实例。因此,有一个对象$scope.formData,表单的所有副本都使用相同的变量(formData.cquarter),因此当您在第一个表单中更改quarter时,第二个表单中的quarter也会更改,因为它是相同的变量。

您需要做的是为每个创建的表单创建一个formData。例如,您可以有一个可变

$scope.allFormDatas = [];

在您的作用域和这个数组中,您将推送旧formData对象的新实例,例如

$scope.addNewForm = function() {
    formCount++;
    $scope.table.fields.push(formCount);
    var newFormData = {};
    $scope.allFormDatas.push (newFormData);
};

现在,您必须在给定的表单中使用newFormData的实例,例如

<select class="form-control" name="Quarters" id="ddlQuarters" ng-model="allFormDatas[$index].quarter">

此外,当您删除表单本身时,当然也必须从数组中删除那些formData对象。