如何计算具有动态ng模型名称的字段

How to calculate fields with dynamic ng-model names

本文关键字:模型 ng 字段 动态 何计算 计算      更新时间:2023-09-26

我的角度应用程序中有一个通过指令生成表的函数。表中的字段需要具有唯一的 ng 模型名称,以便我可以单独计算每个表。我已经用一个计数器解决了唯一的 ng 模型名称,该计数器为每个添加的表上升,并将当前计数添加到每个字段的每个 ng-model 名称的末尾。(请参阅我的 plunkr 链接以获取进一步的解释(。

我的应用程序中有一个函数.js它将对字段求和。当我有静态 ng 模型名称时,该函数运行良好,但我无法弄清楚如何将 ng 模型名称与当前计数连接起来,以便该函数可以在每个 ng-model 后添加一个数字时单独计算每个表。如何修复我的 $scope.total 函数,使其与动态 ng 模型名称一起使用?

我的普伦克

var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.count = 0;
$scope.total = function(count){
var total = 
// I want to parseFloat the $scope.td1 + the current count.
// How does the syntax look when you concat ng-model.
parseFloat($scope.td1 + count || 0) + 
parseFloat($scope.td2 + count || 0) + 
parseFloat($scope.td3 + count || 0) +  
parseFloat($scope.td4 + count || 0) +  
parseFloat($scope.td5 + count || 0);
return total || 0;
}
});

编辑:作为后续问题,我在 plunkr 中添加了一个新输入,该输入应显示生成的前两个表中"总计"的总和。这不像现在这样有效,我不知道为什么。我添加了一个新功能,应该使前两个"总计"夏季化。

使用 : $scope['td1'+计数]

在javascript中,你可以使用指向符号:object.property或命名数组符号:object['property']访问对象属性。

在您的情况下,$scope.td1 + count 将返回 $scope.td1 + count 的值。

$scope.td12 = 10;
$scope.td1 = 3;
count = 2;
$scope.td1 + count; // 5
$scope['td1'+count]; // $scope['td12'] == $scope.td12 == 10

将总函数更新为下面的代码。它应该有效。这是更新的 plunk - http://plnkr.co/edit/vRSQOvRVkUKLZ1ihvBp4?p=preview

$scope.total = function(count){
    // I want to parseFloat the $scope.td1 + the current count.
    // How does the syntax look when you concat ng-model.
    var total = 
    parseFloat($scope["td1" + count] || 0) + 
    parseFloat($scope["td2" + count] || 0) + 
    parseFloat($scope["td3" + count] || 0) +  
    parseFloat($scope["td4" + count] || 0) +  
    parseFloat($scope["td5" + count] || 0);
    return total || 0;
}

更好的方法是创建一个自包含的表指令,该指令跟踪其自己的总数,并在更改时告知父范围。

这样可以避免使用奇怪的计数器,并避免将一个范围与每个输入的属性混杂在一起。

var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
  // the totals for each of the tables
  $scope.totals = [];
  $scope.grandTotal = 0;
  // whenever one of the table's total changes, it calls this function
  // with its new total, so we can update our grand total
  $scope.changeTotal = function(index, total) {
    $scope.totals[index] = total;
    $scope.grandTotal = sum($scope.totals);
  }
});
app.directive('myTable', function() {
  return {
    restrict: 'E',
    scope: {
      onTotalChange: '&'
    },
    templateUrl: 'table.html',
    link: function($scope) {
      $scope.values = [];
      // whenever one of the values the inputs are bound to changes,
      // recalculate the total for this table and tell the parent scope
      $scope.$watchCollection('values', function(values) {
        $scope.onTotalChange({
          total: sum(values)
        });
      });
    }
  }
});
// easy way to sum an array of values in modern browsers
function sum(values) {
  return values.reduce(function(a, b) {
    return a + b
  }, 0);
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="plunker" ng-controller="MainCtrl">
  <p>Grand total: {{grandTotal}}</p>
  <!-- Whenever we click the button, add a new entry to our totals array
       so a new table appears -->
  <button ng-click="totals.push(0)">New table</button>
  <!-- Render a new table for every entry in our totals array.
       Whenever that table's total changes, update its total in the array. -->
  <my-table ng-repeat="i in totals track by $index" on-total-change="changeTotal($index, total)">
  </my-table>
  <!-- This allows the directive to specify a templateUrl of 'table.html' but not
     have to actually fetch it from the server. -->
  <script type="text/ng-template" id="table.html">
    <table>
      <thead>
        <tr>
          <th>head 1</th>
          <th>head 2</th>
          <th>head 3</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>
            <input type="number" ng-model="values[0]">
          </td>
          <td>
            <input type="number" ng-model="values[1]">
          </td>
          <td>
            <input type="number" ng-model="values[2]">
          </td>
        </tr>
        <tr>
          <td>
            <input type="number" ng-model="values[3]">
          </td>
          <td>
            <input type="number" ng-model="values[4]">
          </td>
          <td>
            <input type="number" ng-model="values[5]">
          </td>
        </tr>
      </tbody>
    </table>
  </script>
</div>