如何使用动态ng-model名称

时间:2016-02-10 08:51:29

标签: javascript angularjs

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

我的app.js中有一个函数可以对字段求和。当我有静态ng-model名称时,该功能非常有效,但我无法弄清楚如何将ng-model名称与当前计数连接起来,以便在每个ng-model之后添加一个数字时,该函数可以单独计算每个表。 如何修复我的$ scope.total函数,使其与动态ng-model名称一起使用?

My plunkr

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中添加了一个新输入,它应该显示" total"的总和。在生成的前两个表中。这不是现在的工作,我无法弄清楚为什么。 我添加了一个新函数,它应该总结前两个"总计"。

3 个答案:

答案 0 :(得分:0)

将您的总功能更新为以下代码。它应该工作。这是更新的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;
}

答案 1 :(得分:0)

使用:     $范围[ '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

答案 2 :(得分: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>