ng-bind嵌套依赖



我在使用Angular.js时遇到了一个问题。

我试图建立一个简单的发票web应用程序…
在编辑发票时,用户应该能够插入和删除新项目。

每个项目都有一个只读字段,该字段是小计(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(行)函数中,我可以看到,即使在修改发票中的单个项目时,也会对所有项目调用该函数。

我的意思是,如果我修改了第1项,它不应该重新计算第2项,而应该只更新总额(基于先前计算的第2项的小计,它没有改变…)

我如何优化这个东西?

谢谢。

将函数放在ngBind括号内的问题是,它每次渲染视图时都会调用。只有当每一行的数量或价格发生变化时,才应该计算总数。考虑这个

EDIT:我没看到你在计算每行项目的小计。下面是修改后的解决方案:

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

您可能想要这样做,

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

我把这些放在一起了

最新更新