我有一个通过AngularJS绑定到数据的HTML表。为简单起见,我们只说它有两列,CustomerId和CustomerName。
当用户点击该行(或加号,按钮,链接无关紧要)时,我想展开该行下方的部分,进行ajax调用,并显示结果数据。我还想折叠先前扩展的行,如果有的话。
这看起来像是一个DOM操作任务,我知道如何在JQuery中执行它(或者至少可以解决它),但我想要正确地执行它(即“Angular Way”)。
答案 0 :(得分:6)
今天使用Angular实际上有点困难,但你有几个选择。
首先,我认为最具声明性的解决方案是使<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>
这更简单的原因是,在Angular的当前版本(1.0.x)中,您只能在单个根元素上执行ng-repeat
(尽管看起来这将在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-switch和ng-show / hide创建了一个简单的例子:http://plnkr.co/edit/6kBPIT0Z07ti4BtnGrXj
答案 1 :(得分: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>