2013-06-03 20 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>