我对Angular.js有疑问。
我正在尝试构建一个简单的发票网络应用程序...
编辑发票时,用户应该能够插入和删除新项目。
每个项目都有一个只读字段,即由函数(unit price * qty)
calcSubTotal(row)
在发票末尾有GrandTotal,由函数calcGrandTotal()
计算
前:
HTML:
<div data-ng-repeat='row in rows'>
Unit Price: <input type='text' name='price' data-ng-model='row.unit_price' />
Qty: <input type='text' name='qty' data-ng-model='row.qty' />
<input type='text' readonly value='{{ calcSubTotal(row) }}' />
</div>
<p>GRAND TOTAL: {{ calcGrandTotal() }}</p>
JS(编辑):
$scope.calcSubTotal = function(row) {
console.log(row);
return (row.unit_price * row.qty);
}
$scope.calcGrandTotal = function() {
var total = 0.00;
$($scope.rows).each(function(i, row) {
var x = $scope.calcSubTotal(row);
total += x || 0.00;
});
return total;
};
现在,如果我将console.log("CALLED")
放在calcGrandTotal()
函数中,我会看到它被多次调用。
修改
最糟糕的是,如果我将console.log(行)放在calcSubTotal(row)函数中,我可以看到即使我在修改发票中的单个项目时也会调用所有项目。
我的意思是,如果我修改第1项,它不应该重新计算第2项,而只是更新总计(根据之前计算的第2项小计,它没有改变......)< / p>
我该如何优化这件事?
感谢。
答案 0 :(得分:1)
将函数放在ngBind
括号内的问题在于每次渲染视图时都会调用它。您应该只计算每个行数量或价格变化时的总计。考虑一下这个
编辑:我没有看到您正在计算每个订单项的小计。这是一个经过修订的解决方案:
<div ng-repeat="row in rows">
<input ng-model="row.qty" ng-change="calculateTotals()"/>
<input ng-model="row.price" ng-change="calculateTotals()"/>
<input readonly value="{{row.subTotal}}"/>
</div>
<div ng-bind="grandTotal"></div>
然后在你的控制器/指令中执行类似这样的操作
$scope.calculateTotals = function() {
var grandTotal = 0;
angular.forEach($scope.rows, function(row) {
row.subTotal = row.qty * row.price;
grandTotal += row.subTotal;
});
$scope.grandTotal = grandTotal;
}
注意:在您收到行数据后,您可能还需要在控制器中的某处调用它:
$http.get('/my/invoice/').success(function(rows){
$scope.rows = rows;
$scope.calculateTotals();
});
答案 1 :(得分:0)
你可能想做这样的事情,
HTML(与您的相同)
<div data-ng-repeat='row in rows'>
<p>row {{$index}}</p>
Unit Price: <input type='text' name='price' data-ng-model='row.unit_price' />
<br>
Qty: <input type='text' name='qty' data-ng-model='row.qty' />
<br>
<input type='text' readonly value='{{ calcSubTotal(row) }}'>
</div>
<p>GRAND TOTAL: {{ calcGrandTotal() }}</p>
JS
angular.module("app", []).controller('ctrl', function($scope){
$scope.rows = [{unit_price: 0, qty: 0}, {unit_price: 0, qty: 0}];
$scope.calcSubTotal = function(row){
return parseFloat(row.unit_price) * parseFloat(row.qty);
}
$scope.calcGrandTotal = function() {
var total = 0.00;
$($scope.rows).each(function(i, row) {
var x = $scope.calcSubTotal(row);
total += x || 0.00;
});
return total;
};
});
我把它们放在一个here中。