2013-06-03 56 views
4

我有一個通過AngularJS綁定到數據的HTML表格。爲了簡單起見,我們只是說它有兩列,CustomerId和CustomerName。使用AngularJS展開/合同表部分

當用戶點擊行(或加號,按鈕,鏈接,無關緊要)時,我想展開該行下面的部分,進行ajax調用並顯示結果數據。如果有的話,我也想摺疊先前擴展的行。

這看起來像是一個DOM操作任務,我知道如何在JQuery中做到這一點(或者至少可以弄明白),但我想正確地做到這一點(即「Angular Way」)。

回答

6

這其實是有點難以做到今天角,但你有幾個選項。

首先,我認爲最陳述的解決辦法是有一個<tr>與正常狀態,並與編輯狀態<tr>

<tr ng-show="edit"><td><input ng-model="model.name" ... 
<tr ng-hide="edit"><td>{{model.name}} ... 

替代(實際上是簡單)就是這樣做在列<td>

<tr> 
    <td ng-show="edit"><input ng-model="model.name" ... 
    <td ng-hide="edit">{{model.name}} ... 
</tr> 

的原因,這是更簡單的是,在角的當前版本(1.0.x的),你只能做ng-repeat一個根元素上(雖然它看起來像這樣WIL l在v 1.2.x中更改:multi-element directives)。幸運的是你被允許在HTML中使用多個<tbody>標籤,所以這實際上是有效的:

<tbody ng-repeat="model in models"> 
    <tr ng-show="edit"><td><input ng-model="model.name" ... 
    <tr ng-hide="edit"><td>{{model.name}} ... 
<tbody> 

注意,使用ng-hide只隱藏從DOM元素。如果你關心性能(巨大的表或移動設備)ng-switch(或1.2.x的ng-if)可能是一個更好的選擇,因爲它消除隱藏部分從DOM:

<tbody ng-repeat="model in models" ng-switch="row.edit" ng-init="row={}"> 
    <tr ng-switch-when="true"> 
     <td><input type="text" ng-model="model.customerId" disabled /></td> 
     <td><input type="text" ng-model="model.customerName" /></td> 
     <td ng-click="row.edit=false">done</td> 
    </tr> 
    <tr ng-switch-default> 
     <td>{{model.customerId}}</td> 
     <td>{{model.customerName}}</td> 
     <td ng-click="row.edit=true">edit</td> 
    </tr> 
    </tbody> 

更新:我已經添加了第三種使用ng-include的解決方案:

這種方法可能不是最具說明性的,但它工作得很好。我創建了兩個不同的行模板(這些模板可以是單獨的文件或內嵌爲ng-templates,如我的示例),然後使用ng-include在兩個模板之間切換。需要注意的是這個工作沒有額外的<tbody>

<script type="text/ng-template" charset="utf-8" id="display.html"> 
    <td>{{model.customerId}}</td> 
    <td>{{model.customerName}}</td> 
    <td ng-click="row.edit=true">edit</td> 
</script> 

<script type="text/ng-template" charset="utf-8" id="edit.html"> 
    <td><input type="text" ng-model="model.customerId" disabled /></td> 
    <td><input type="text" ng-model="model.customerName" /></td> 
    <td ng-click="row.edit=false">done</td> 
</script> 

<table border="0"> 
    <tr> 
    <th>CustomerId</th> 
    <th>CustomerName</th> 
    <th>Edit</th> 
    </tr> 

    <tr ng-repeat="model in models" 
     ng-include="{true:'edit.html',false:'display.html'}[row.edit]" 
     ng-init="row={edit:false}"></tr> 
</table> 

我用NG-開關和NG-顯示/隱藏創建了一個簡單的例子:http://plnkr.co/edit/6kBPIT0Z07ti4BtnGrXj

+0

太棒了!我使用了ng-switch選項。 –

0

這可以通過指令完成。 DOM操作通常通過指令完成。 http://plnkr.co/edit/0Z36Q3EEvP9GElzuAe5M

var app = angular.module('App', []); 
     angular.module('App').directive(
       'tab', ['$http', 
        function ($http) { 
         return { 
          template: '<table border="1" ng-click="click();show=!show" ><tr >' + 
            '<th >ID</th>' + '<th>customer</th>' + 
            ' </tr>' + 
            '<tr ng-show="show" ng-repeat="data in datas"><td>{{data[0]}}</td><td>'+ 
            '{{data[1]}}</td></tr>' + 
            '</table><br/>', 
          restrict: 'A', 
          link: function postLink(scope,element) { 
           scope.show =false; 
           scope.click = function() { 
            //console.log(scope.datas); 
            if (scope.datas ==null) { 
             $http.get('/data').success(function (data) { 
              scope.datas =data; 
             }).error(function() { 
              scope.datas = [[1,"i am customer 1"],[3,"i am customer 2"]]; 
             }) 
            } 
           } 
          } 
         }; 
        } 
       ]); 

HTML:

<body ng-app="App"> 
<div tab></div> 
</body>