2014-02-11 72 views
3

結構類似假設數據:如何使用angular.js將多個數組的數據顯示爲html表格?

[ 
{name: 'first', data1: [1,2,3], data2: [4,5]}, 
{name: 'second', data1: [9,8,7], data2: [6,6,4,5]}, 
... 
] 

(注data1和data2的不固定長度和不一定是相同的長度)。

我想創建一個HTML表所示:

<table> 
<thead> 
    <th> Name </th> 
    <th> Data 1 </th> 
    <th> Data 2 </th> 
</thead> 
<tbody> 
    <tr> 
    <td rowspan="4">first</td> 
    <td>1</td> 
    <td>4</td> 
    </tr> 
    <tr> 
    <td>2</td> 
    <td>5</td> 
    </tr> 
    <tr> 
    <td>3</td> 
    <td>&nbsp;</td> 
    </tr> 
    <tr> 
    <td>&nbsp;</td> 
    <td>&nbsp;</td> 
    </tr> 

    <tr> 
    <td rowspan="5">first</td> 
    <td>9</td> 
    <td>6</td> 
    </tr> 
    <tr> 
    <td>8</td> 
    <td>6</td> 
    </tr> 
    <tr> 
    <td>7</td> 
    <td>5</td> 
    </tr> 
    <tr> 
    <td>&nbsp;</td> 
    <td>5</td> 
    </tr> 
    <tr> 
    <td>&nbsp;</td> 
    <td>&nbsp;</td> 
    </tr> 
</tbody> 
<table> 

注意,在顯示有數據的每一列中的最後一位後至少一個額外的空單元格。我希望這個單元格是data1和data2中每個的第一個空單元格,它具有一個ng-click處理程序,如果單擊該處理程序,該處理程序會在該列中顯示輸入而不是%nbsp;哪裏可以輸入新的價值。

完成此操作的最佳方法是什麼?

[ { name: 'first', rowsNeeded: '4', data: [ [1,4], [2,5], [3, undefined], [undefined, undefined]], ... ] 

目前我可以由具有在其上觀看第一和當第一修改它變平的數據,以便在上述數據將被存儲在另一個變量作爲範圍的第2可變幾乎創建上述結構

,然後使其像

<tbody ng-repeat="item in flattenedData"> 
    <tr ng-repeat="data in item.data"> 
     <td ng-if="$first" rowspan="{{data.rowsNeeded}}">{{data.name}}</td> 
     <td>{{data[0] == undefined ? '&nbsp;' : macroData[0] }}</td> 
     <td>{{data[1] == undefined ? '&nbsp;' : macroData[1] }}</td> 
    </tr> 
</tbody> 

但我想知道的幾件事情。一,我是否真的需要使用watch語句來創建表或者是否有一個更清晰的方法?二,我不知道如何添加點擊事件,所以我可以添加一列而不是'& nbsp'。最後,真的有必要爲每一行都有不同的tbody標籤嗎?

感謝您的幫助!

回答

3

一般的想法是將數據格式提取到過濾器中。從那裏開始,我將所有內容組合成指令來簡化表格組件的使用。這個例子(JSBin)只顯示過濾器和模板,非最佳,但工作:

<table> 
    <thead> 
     <tr> 
      <th>Name</th> 
      <th ng-repeat="key in datas[0]|dataKeys"> 
       Data {{$index+1}} 
      </th> 
     </tr> 
    </thead> 
    <tbody ng-repeat="set in datas"> 
     <tr ng-repeat="row in (set|setMaxLength|range)"> 
      <td 
       rowspan="{{(set|setMaxLength)+1}}" 
       ng-if="!$index" 
      > 
       {{set.name}} 
      </td> 
      <td ng-repeat="data in (set|setDatas)"> 
       {{data[$parent.$index]}} 
      </td> 
     </tr> 
     <tr> 
      <td 
       ng-repeat="data in (set|setDatas)" 
       ng-click="editing = true" 
      > 
       <span ng-if="!editing">&nbsp;</span> 
       <form 
        ng-submit="data[data.length] = input.value" 
        name="input" 
       > 
        <input 
         type="text" 
         ng-if="editing" 
         ng-model="input.value" 
         autofocus 
        > 
       </form> 
      </td> 
     </tr> 
    </tbody> 
</table> 
angular 
.module("app", []) 
.controller("ctrl", function($scope) { 
    $scope.datas = [{ 
     name: 'first', 
     data1: [1, 2, 3], 
     data2: [4, 5] 
    }, { 
     name: 'second', 
     data1: [9, 8, 7], 
     data2: [6, 6, 4, 5] 
    }]; 
}) 
.filter("range", function() { 
    return function(length) { 
     return Array.apply(0, Array(length)) 
     .map(function(_, i) { 
      return i; 
     }) 
    } 
}) 
.filter("dataKeys", function() { 
    return function(set) { 
     return Object.keys(set) 
     .filter(function(key) { 
      return key.indexOf("data") !== -1; 
     }) 
    } 
}) 
.filter("setDatas", function($filter) { 
    return function(set) { 
     return $filter("dataKeys")(set) 
     .map(function(key) { 
      return set[key] 
     }); 
    } 
}) 
.filter("setMaxLength", function($filter) { 
    return function(set) { 
     return $filter("dataKeys")(set) 
     .map(function(key) { 
      return set[key].length; 
     }) 
     .sort().pop(); 
    } 
}) 
+0

這是使用過濾器一種巧妙的方法!非常感謝你的回答。 – evan

相關問題