Reputation: 2585
I am trying to implement Hierarchical Grid
in my Angular 2
application similar to this one http://demos.telerik.com/kendo-ui/grid/hierarchy
So I started out by creating two components
. The Parent Component
is for parent table and Child Component
is for child table. So when click on row from parent table, the child table will load right below it (like above example).
This is how my html looks like
<div class="row">
<div class="col-md-12">
<h1>{{pageTitle}}</h1>
<table class="table table-striped">
<thead>
<tr>
<td></td>
<td>User Name</td>
<td>Email</td>
<td>Billing Method</td>
</tr>
</thead>
<tbody>
<tr class="master-row" *ngFor="#invoice of invoices; #i = index">
<td><button (click)="getDetail(invoice)"><i class="glyphicon glyphicon-chevron-right"></i></button></td>
<td>{{invoice.username}}</td>
<td>{{invoice.email}}</td>
<td>{{invoice.billingMethod}}</td>
</tr>
</tbody>
</table>
</div>
</div>
But I am having two issues:
1) How to load child table on a correct location in DOM
? The problem is when my parent table render, all of it's rows gets created using ngFor
directive. Now when click on a row, how to load it's child table right below it? How to identify the location?
2) In order to load child table, I was thinking to use DynamicComponentLoader
Class, but looks like the communication between Components
won't be possible when using DCL
.
Please suggest
Upvotes: 0
Views: 2018
Reputation: 16540
I was able to fulfill your requirements using the template syntax of ngFor
pre 2.0.0-beta.17 syntax:
<template ngFor #item [ngForOf]="items" #i="index">
<tr>...</tr>
</template>
2.0.0-beta.17 syntax:
<template ngFor let-invoice [ngForOf]="invoices" let-i="index">
<tr>...</tr>
</template>
In your situation it will be:
<template ngFor let-invoice [ngForOf]="invoices" let-i="index">
<tr class="master-row" *ngFor="#invoice of invoices; #i = index">
<td><button (click)="getDetail(invoice)"><i class="glyphicon glyphicon-chevron-right"></i></button></td>
<td>{{invoice.username}}</td>
<td>{{invoice.email}}</td>
<td>{{invoice.billingMethod}}</td>
</tr>
<tr *ngIf="isInvoiceOpened(i)">
<td colspan="100">
<child-table [details]="details"></child-table>
</td>
</tr>
</template>
The isInvoiceOpened()
function will return true if that particular row is opened. Which means you should have an array to hold opened rows indexes, i.e.
_openedDetails = [];
isInvoiceOpened(i){
return this._openedDetails.indexOf(i)>-1;
}
getDetail(i){
let index = this._openedDetails.indexOf(i);
if(index > -1)
this._openedDetails.splice(index,1);
else
this._openedDetails.push(i);
}
Upvotes: 1