Angular.js:ng-bind嵌套依赖项

时间:2014-05-21 18:21:13

标签: angularjs

我对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>

我该如何优化这件事?

感谢。

2 个答案:

答案 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中。