2014-02-24 67 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。然後,無論您有多少行/列號,該指令都可以構建表。