2014-02-24 42 views
2

我想根据控制器设计一个表。基本上像一个简单的控制器:使用angularjs修改html表的列数

 

function Main($scope) { 
    $scope.row = {   
     columns: [{ 
      type: 'single', 
      name: 'col1' 
     }, { 
      type: 'double', 
      name: 'col2' 
     }] 
    }; 
} 
 

我想改变的基于类型的列tr S中的数目。基本上所需的输出是:

<table> 
    <tr>   
     <!-- for column in columns --> 
     <!-- If column.type is single have single td --> 
     <!-- If column.type is double have two td --> 
     <td>col1</td>   
     <td>col2</td> 
     <td>col2</td> 
    </tr> 
</table> 

我有一个小提琴,你可以玩:http://jsfiddle.net/basarat/7G6fF/

我一直在使用NG重复,跨度尝试,但问题是,span从DOM由去除浏览器,因为它是TR的无效子:

<table> 
    <tr>    
     <!-- for column in columns --> 
     <!-- If column.type is single have single td --> 
     <!-- If column.type is double have two td --> 
     <span ng-repeat="column in row.columns"> 
      <span ng-switch="column.type"> 
       <span ng-switch-when="single"><td>{{column.name}}</td></span> 
       <span ng-switch-when="double"><td>{{column.name}}</td><td>{{column.name}}</td></span> 
      </span> 
     </span> 
    </tr> 
</table> 
+0

你在这里呈现的方式(在小提琴中)看起来不像表格数据。你能否详细说明如果每个表格单元格的数量可能不同,那么多行将不得不进行交互?(我至少期待在tr上重复ng)。也许解决方案是不使用表? –

+0

@SimonGroenewolt将有一个ng-repeat的'tr's。它是按行排列的,但是我简化了这个例子,只使用了一个'row'和一个'tr'来隐藏复杂度 – basarat

+0

ok,理解。但是,如果每行数据可能不同,为什么还要使用表格呢? –

回答

4

我有一个使用ng-repeat-startng-repeat-end语法的工作示例。不是很优雅,但你给出的数据集,这是我能想出的最好的:

<table> 
    <tr>    
     <td ng-repeat="column in row.columns | filter:isSingle"> 
      {{column.name}} 
     </td> 
     <td ng-repeat-start="column in row.columns | filter:isDouble"> 
      {{column.name}} 
     </td> 
     <td ng-repeat-end> 
      {{column.name}} 
     </td> 
    </tr> 
</table> 

isSingleisDouble滤镜功能在你的控制器中定义:

$scope.isSingle = function(column){ 
    return column.type === 'single'; 
} 

$scope.isDouble = function(column){ 
    return column.type === 'double'; 
} 

这里的工作小提琴samplehttp://jsfiddle.net/7G6fF/3/

UPDATE

根据评论中的@PeterAlbert问题,我可以设法保留订单的唯一方法是将列数据转换为更多ngRepeat兼容格式。 @MadaManu的回答有点启发。我真的认为这是要走的路线。下面的例子转换控制器内部的列数据,这很好,但你可以明显地在你的服务器端格式化它。

将您的列:

$scope.row = { 
    columns: [{ 
     type: 'single', 
     name: 'col1' 
    }, { 
     type: 'double', 
     name: 'col2' 
    }] 
}; 

$scope.transformedColumns = []; 

$scope.$watchCollection('row.columns', function (newColumns, oldColumns) { 
    $scope.transformedColumns = transformColumns(newColumns); 
}); 

function transformColumns(columns) { 
    var c = []; 
    angular.forEach(columns, function (column) { 
     if (column.type === 'single') { 
      c.push(column); 
     } else if (column.type === 'double') { 
      c.push(column); 
      c.push(column); 
     } 
    }); 
    return c; 
} 

一旦转化它只是在你的HTML中使用的标准ngRepeat语法的事:

<table> 
    <tr> 
     <td ng-repeat="column in transformedColumns track by $index"> 
      {{column.name}} 
     </td> 
    </tr> 
</table> 

更新fiddle is herehttp://jsfiddle.net/7G6fF/5/为了测试我添加两个按钮可以添加单列或双列,以便您可以实时看到影响,这也是0123d代码在小提琴中的原因。

+0

有趣的解决方案+1!但是,这会改变列的顺序,例如,如果数组中的第一个条目将是double,第二个条目将是“single”,则后者将首先显示。有什么办法保持原来的秩序? –

+0

@PeterAlbert我能想到的唯一方法是使用自定义指令。如果我今天晚上得到一些时间,我会给它一个破解并报告。 – Beyers

+1

@PeterAlbert查看更新的答案 – Beyers

1

我会结构中的JSON将沿着这些路线的东西的方式:

[ 
    ["col1 row1", "col2 row1"], 
    ["col1 row2", "col2 row2"], 
    ["col1 row3", "col2 row3"] 
] 

因此然后在指令建表,你可以有这样的:

<table class="table"> 
    <tbody> 
     <tr data-ng-repeat="cell in table.cells track by $index"> 
      <td data-ng-repeat="data in cell track by $index"> 
       {{data}} 
      </td> 
     </tr> 
    </tbody> 
</table> 

*您的table.cells是上面显示的JSON。然后,无论您有多少行/列号,该指令都可以构建表。