【问题标题】:Add new column to table using existing values使用现有值向表中添加新列
【发布时间】:2016-03-29 05:51:03
【问题描述】:

我正在使用 angularjs 并有一个从两个范围对象构建的表。如果有某种功能,我可以自己添加列,那就太好了。最大的问题是我想使用现有值并尝试在我的新列中使用它们。那可能吗?还是我必须在服务器端建立列然后返回?

PLUNKER

<!doctype html>
<html ng-app="plunker">

<head>
<script data-require="angular.js@*" data-semver="1.2.0" src="http://code.angularjs.org/1.2.0/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>

<body>
<div ng:controller="MainCtrl">
    <table border="1">
        <thead style="font-weight: bold;">
            <tr>
                <th class="text-right" ng-repeat="column in columnsTest" ng-if="column.checked" ng-bind="column.id"></th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="row in rows">
                <td ng-repeat="column in columnsTest" ng-if="column.checked">
                    {{ row[column.value] }}
                </td>
            </tr>
        </tbody>
    </table>
    <br><br>
  <input type="button" value="Add new column"  ng-click="addColumn()" />

  <br><br><br>
  <p ng-repeat="c in columnsTest">Column {{$index}}: {{c}}</p>
</div>

<script>
    var app = angular.module('plunker', []);

    app.controller('MainCtrl', function($scope, $filter) {

      $scope.addColumn = function() {
        var newCol = { id: 'Value4', checked: true, value: 'Value1 + Value2 + Value3' }

        $scope.columnsTest.push(newCol);
      }

        $scope.columnsTest = [{
            id: 'Value1',
            checked: true,
            value: 'Value1'
        }, {
            id: 'Value2',
            checked: true,
            value: 'Value2'
        }, {
            id: 'Value3',
            checked: true,
            value: 'Value3'
        }];

        $scope.rows = [{
            id: 1,
            "Value1": 911,
            "Value2": 20,
            "Value3": 20
        }, {
            id: 2,
            "Value1": 200,
            "Value2": 20,
            "Value3": 20
        }];
    });
</script>

【问题讨论】:

  • 您需要$scope.rows 的数据结构,就像您在代码中使用的那样吗?我认为使用二维数组会更容易。
  • @AWolf 看起来怎么样?我可以改变结构。

标签: angularjs html-table


【解决方案1】:

您可以使用$parse 服务。

$parse 注入您的控制器并添加一个新方法:

$scope.getCellValue = function(row, column) {

  var getter = $parse(column.value);
  return getter(row);

  // Alternatively:
  // return $parse(column.value)(row);
};

像这样使用它:

<tr ng-repeat="row in rows">
  <td ng-repeat="column in columnsTest" ng-if="column.checked">
    {{ getCellValue(row, column) }}
  </td>
</tr>

演示: http://plnkr.co/edit/DVF2LXeZPqCL1Ik3EyVf?p=preview


解释:

$parse 服务接受一个字符串表达式进行编译并返回一个 getter 函数。在您的示例中,我们使用 column.value:

var columnValue = 'Value1 + Value2 + Value3';
var getter = $parse(columnValue);

返回的getter 函数接受一个上下文对象,表达式应该被评估。在您的示例中,我们使用 row 对象:

var row = { id: 1, "Value1": 911, "Value2": 20, "Value3": 20 };
var result = getter(row);

基本上$parse 服务使用字符串表达式和上下文对象 然后去:

您想要 Value1 + Value2 + Value3,并且您想要检索这些值 来自行对象。

如下图:

var result = row['Value1'] + row['Value2'] + row['Value2'];

【讨论】:

  • 是否可以为值添加过滤器?例如。 |号码?
  • 所有单元格使用相同的过滤器,还是需要特定的过滤器?
  • 如果您需要对所有单元格使用相同的过滤器:{{ getCellValue(row, column) | currency }}。如果您需要具体:value: 'Value1 + Value2 + Value3 | currency'
【解决方案2】:

使用二维数组,您可以像这样构造数据:

$scope.rows = [
          [911,20,30], // index 0 of 1st dim = 1st row; index 0,1,2 of 2nd dim = cells
          [200,20,30]  // index 1 of 1st dim = 2nd row
        ];

有了这个,您可以使用两个循环来获取单元格并进行计算,第一个循环用于行,第二个循环用于单元格值。

请看下面的演示或plunkr

在演示中,我创建了一个函数来进行计算,如果你还传递一个像 [0,1] 这样的数组,它将告诉函数只对 col0 和 col1 值求和。

var app = angular.module('plunker', []);
        
        app.controller('MainCtrl', function($scope, $filter) {
          
          function sumRows(data, values2sum) {
            // e.g. data = [ [11, 12, 13], [21, 22, 23] ]
            // new col = [ 32, 34, 46]  // sum all
            // new col = [ 32, 34, 0 ] // sum value1 & 2 
            // --> values2sum = [ 0, 1 ]
           
            if ( angular.isUndefined(values2sum) ){
              var all = true;
              var value2sum = [];
            }
            
            angular.forEach(data, function(row, rowIndex) {
              rowSum = 0;
              angular.forEach(row, function(cell, colIndex) {
                if ( all || values2sum.indexOf(colIndex) != -1 ) {
                  rowSum += cell;
                }
              });
              row.push(rowSum);
            })
          }
          
          $scope.addColumn = function() {
            var rowSum, newRow = [], colId = $scope.columnsTest.length + 1;
            
            $scope.columnsTest.push({
                id: 'Value'+ colId,
                checked: true,
                value: 'Value'+colId
            }); // rename columnsTest to tableHeading
            
            //sumRows($scope.rows, [0,2]); // add value1 + value3
            sumRows($scope.rows); // complete sum
            
            //var newCol = { id: 'Value4', checked: true, value: 'Value1 + Value2 + Value3' }
            
            //$scope.columnsTest.push(newCol);
          }

            $scope.columnsTest = [{
                id: 'Value1',
                checked: true,
                value: 'Value1'
            }, {
                id: 'Value2',
                checked: true,
                value: 'Value2'
            }, {
                id: 'Value3',
                checked: true,
                value: 'Value3'
            }];

            /*$scope.rows = [{
                id: 1,
                "Value1": 911,
                "Value2": 20,
                "Value3": 20
            }, {
                id: 2,
                "Value1": 200,
                "Value2": 20,
                "Value3": 20
            }];*/
            
            $scope.rows = [
              [911,20,30],
              [200,20,30]
            ]
            
        });
<script data-require="angular.js@*" data-semver="1.2.0" src="http://code.angularjs.org/1.2.0/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

<div ng-app="plunker" ng:controller="MainCtrl">
  <table border="1">
    <thead style="font-weight: bold;">
      <tr>
        <th class="text-right" ng-repeat="column in columnsTest" ng-if="column.checked" ng-bind="column.id"></th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="row in rows track by $index">
        <td ng-repeat="cell in row track by $index">
          <!--ng-if="column.checked">-->
          {{ cell }}
        </td>
      </tr>
    </tbody>
  </table>
  <br>
  <br>
  <input type="button" value="Add new column" ng-click="addColumn()" />

  <br>
  <br>
  <br>
  <p ng-repeat="c in columnsTest">Column {{$index}}: {{c}}</p>
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-25
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-13
    相关资源
    最近更新 更多