编辑这是这个问题的关键
我有一个会计交易的主明细表。主部分只包含两个字段名称和类型。详细信息部分可以有两个或多个条目,每个条目都有 AccountId、Debit 和 Credit 字段。表单看起来像
您可以看到每个条目都有一个删除按钮,因此如果我们有两个以上的条目,我们可以随机删除任何条目。表单 html 如下所示
<body data-ng-app="transactions">
<div data-ng-controller="transactionsController">
<form role="form" name="transactionForm" novalidate data-ng-submit="create()">
<div class="row">
<div class="col-md-2">
</div>
<div class="col-md-4">
<h2 class="form-login-heading">Create Transaction</h2>
<div data-ng-repeat="error in errors" class="alert alert-danger">
{{error[0]}}
</div>
<input type="text" name="name" class="form-control" placeholder="Name" data-ng-model="transaction.Name" required autofocus>
<div>
<span class="error" data-ng-show="transactionForm.name.$error.required && submitted">Please enter Name</span>
</div>
<input type="text" name="type" class="form-control" placeholder="Type" data-ng-model="transaction.Type" required>
<div>
<span class="error" data-ng-show="transactionForm.type.$error.required && submitted">Please enter Type</span>
</div>
<!--<input type="text" readonly name="number" class="form-control" placeholder="Number" data-ng-model="transaction.Number">
<input type="checkbox" data-ng-model="transaction.IsFinalized" /> <label>Finalize</label>-->
<table>
<tr>
<th>Account</th>
<th>Debit</th>
<th>Credit</th>
<th> </th>
</tr>
<tr data-ng-form="entryForm" data-ng-repeat="entry in transaction.Entries track by $index">
<td>
<input required name="accountId" data-ng-model="entry.AccountId" class="form-control" />
<span class="error" data-ng-show="entryForm.accountId.$error.required && submitted">Please select an account</span>
</td>
<td>
<input type="text" name="debit" data-ng-required="!entry.CreditAmount" class="form-control" placeholder="Debit" data-ng-model="entry.DebitAmount">
<span class="error" data-ng-show="entryForm.debit.$error.required && submitted">Debit is required</span>
</td>
<td>
<input type="text" data-ng-focus="checkAddRow($index)" name="credit" data-ng-required="!entry.DebitAmount" class="form-control" placeholder="Credit" data-ng-model="entry.CreditAmount">
<span class="error" data-ng-show="entryForm.credit.$error.required && submitted">Credit is required</span>
</td>
<td><button data-ng-show="transaction.Entries.length>2" class="btn btn-md btn-info " type="button" data-ng-click="deleteRow($index)">delete</button></td>
</tr>
<tr>
<td>Total</td>
<td><input readonly name="totalDebit" type="text" class="form-control" placeholder="Total Debit" data-ng-value="totalDebit()"></td>
<td><input readonly name="totalCredit" compare-to="totalDebit" type="text" class="form-control" placeholder="Total Credit" data-ng-value="totalCredit()"></td>
</tr>
<tr>
<td></td>
<td><b>Difference</b></td>
<td>
<input name="difference" readonly type="text" class="form-control" data-ng-value="difference()">
<!--<span class="error" data-ng-show="submitted && !differencezero">Difference should be 0</span>-->
</td>
</tr>
</table><br />
<button class="btn btn-md btn-info" type="submit">Create</button>
<button class="btn btn-md btn-info" data-ng-show="transaction.Entries.length<15" type="button" data-ng-click="addRow()">Add Row</button>
<div data-ng-hide="message == ''" class="alert alert-danger">
{{message}}
</div>
</div>
<div class="col-md-4">
</div>
<div class="col-md-2">
</div>
</div>
</form>
<style type="text/css">
.error {
color: red;
}
</style>
<pre>{{transactionForm.entryForm|json}}</pre>
</div>
我的要求是,当焦点放在最后一个条目的信用输入上时,新条目应该自动添加到 UI 中。我通过在我的控制器上使用addRow
and方法来做到这一点。checkAddRow
这些方法如下
$scope.checkAddRow = function (index) {
if (index == $scope.transaction.Entries.length - 1) {
$scope.addRow();
}
}
$scope.addRow = function () {
entry = {
EntryTime: '',
DebitAmount: '',
CreditAmount: '',
AccountId: ''
};
$scope.transaction.Entries.push(entry);
console.log($scope.transactionForm);
}
$scope.deleteRow = function (index) {
$scope.transaction.Entries.splice(index, 1);
console.log($scope.transactionForm);
}
同样,这部分很好并且运行良好。但我有另一个要求,如果最后一个条目没有被使用,它不应该导致表单无效。它应该从transaction.Entries
收集中删除,其余数据应该正常保存。为了实现这一点,我create
定义了$scope
如下所示的函数
$scope.create = function () {
$scope.submitted = true;
if ($scope.transactionForm.entryForm && $scope.transactionForm.entryForm.$invalid && $scope.transactionForm.entryForm.$pristine) {
$timeout(function () {
$scope.deleteRow($scope.transaction.Entries.length - 1);
});
$timeout(function () {
console.log('From time out', $scope.transactionForm.$valid);
console.log($scope.transactionForm.$valid);
if (!$scope.transactionForm.$valid) return;
alert('data saved!');
console.log($scope.transactionForm);
//$scope.transactionForm.name.focus();
}, 200);
}
else {
if ($scope.transactionForm.$valid) {
alert('data saved 2');
}
}
}
你可以看到什么create
功能在做什么。它正在检查entryForm (ng-form)
主窗体中是否存在(transactionForm
),然后检查是否entryForm
存在$invalid
,$pristine
如果所有这些标志都为真,那么我删除最后一个条目$scope.transaction.Entries
并保存数据(当前显示数据已保存的警报)$timeout
。如果我不使用超时,那么表单是无效的,所以我必须等待 200 毫秒才能$valid
在删除最后一行后检查表单标志。entryForm
但令我惊讶的是,当我从 create 函数中删除最后一行时,外部没有附加transactionForm
. 另一方面,如果我使用 UI 上存在的删除按钮删除条目,entryForm
则存在于 maintransactionForm
中。谁能解释为什么会这样。我已经添加了<pre>{{transactionForm|json}}</pre>
最后查看它何时可用,何时在主窗体上不可用。我创建了一个plunk来说明我的意思。只需在 master 部分的两个输入字段中添加一些数据,在两个条目的 accountid 字段中输入一些数据,当您到达第二个(最后一个)条目的 Credit 输入时,将自动添加一个新条目。忽略该行,只需按下创建按钮。最后一个条目将被删除,数据将保存,但entryForm
将不再存在。我不确定我做错了什么。