4

我有一个通过 AngularJS 绑定到数据的 HTML 表。为简单起见,假设它有两列,CustomerId 和 CustomerName。

当用户单击该行(或加号、按钮、链接,无所谓)时,我想在该行下方展开一个部分,进行 ajax 调用,并显示结果数据。如果有的话,我还想折叠之前展开的行。

这似乎是一个 DOM 操作任务,我知道如何在 JQuery 中完成它(或者至少可以弄清楚),但我想正确地完成它(即“Angular 方式”)。

4

2 回答 2

6

今天用 Angular 做这件事实际上有点困难,但你有几个选择。

首先,我认为最具声明性的解决方案是具有<tr>正常状态的 a<tr>和具有编辑状态的 a :

<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>

这更简单的原因是在当前版本的 Angular (1.0.x) 中,您只能ng-repeat对单个根元素执行此操作(尽管看起来这在 v 1.2.x: multi-element directives中会有所改变)。幸运的是,您可以<tbody>在 html 中使用多个标签,所以这实际上是有效的:

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

请注意, usingng-hide仅对 dom 隐藏元素。如果您担心性能(大型表或移动设备)ng-switch(或ng-if在 1.2.x 中)可能是更好的选择,因为它从 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-switch 和 ng-show/hide 创建了一个简单的示例:http: //plnkr.co/edit/6kBPIT0Z07ti4BtnGrXj

于 2013-06-03T08:05:33.170 回答
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>
于 2013-06-03T07:37:07.093 回答