Expand / Open contract table with AngularJS

I have an HTML table bound to data via AngularJS. To make it simple, let's say it has two columns: CustomerId and CustomerName.

When the user clicks on the line (or the plus sign, button, link, it does not matter), I would like to expand the section under the line, make an ajax call and display the resulting data. I would also like to collapse the previously extended line, if any.

This is similar to the task of manipulating the DOM, and I know how to do it in jQuery (or at least can figure it out), but I would like to do it right (i.e. "path w500>").

+4
source share
2 answers

This is actually a little tricky to do with Angular today, but you have several options.

Firstly, I think the most declarative solution would be to have a <tr> with a normal state and a <tr> with an edit state:

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

an alternative (which is actually simpler) is to do this in the <td> column

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

The reason for this is simpler because in the current version (1.0.x) of Angular, you can only do ng-repeat on a single root element (although it looks like this will change in version 1.2.x: multi-element directives ). Fortunately, you are allowed to use multiple <tbody> tags in html, so this is really valid:

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

Note that using ng-hide only hides the element from dom. If you are concerned about performance (huge tables or mobile devices), ng-switch (or ng-if in 1.2.x) might be the best option as it removes the hidden part from 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> 

Update . I added a third solution that uses ng-include:

This method may not be the most declarative, but it works very well. I created two different line templates (these can be separate files or embedded as ng templates, as in my example), and then I use ng-include to switch between the two templates. Note that this works without an extra <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> 

I created a simple example using ng-switch and ng-show / hide: http://plnkr.co/edit/6kBPIT0Z07ti4BtnGrXj

+6
source

This can be done using directives. DOM manipulation is usually done using directives. 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> 
0
source

Source: https://habr.com/ru/post/1484116/


All Articles