So I am working on a feature for the table in my app. I have done an abstraction over the ngx-datatable as a component which acts as a facade for other components in my app (someComponent => FacadeTableComponent => Ngx-DataTable).
The columns are created in the FacadeTableComponent based on someComponent, and passed as an input to the NgxDataTable.
But now I want to add a tree view to the datatable (that works) but I want the FacadeTableComponent to set a default first column with a button that does the tree collapsing/expanding. So I thought that the default column could be defined as a ngx-datatable-column in the FacadeTableComponent html template. The problem seems that the input columns seem to overwrite my default column.
Now I tried to somehow grab the ngx-datatable-column with a @ViewChild and unshift it to the generated columns in the FacadeTableComponent, but I am not able to grab it as a directive, rather as a ElementRef.
I could of course just define a default column in the .ts file and generate it when I generate the rest of the columns, but I want to know if it is possible to do it the way I described it in the title.
The reason for this default column is that when I set one of the existing columns as a treeView column, the ngx datatable adds a default button, even if I provide my own template to the cell, and I want to provide my own button in the template.
<ngx-datatable #ngxDataTable class="datatable" [rows]="collection" [columnMode]="columnMode"
[footerHeight]="footerHeight" [selectionType]="selectionType" [sortType]="sortType" [sorts]="sorts"
[rowIdentity]="rowIdentity" [messages]="tableMessages" [selected]="selectedRows" [columns]="columns"
[headerHeight]="headerHeight" [rowHeight]="rowHeight" [scrollbarV]="true" [scrollbarH]="true"
(select)="onSelect($event)" (activate)="onActive($event)" [externalSorting]="true" [rowClass]="rowCssClass"
[sortType]="'single'" [treeFromRelation]="'MasterId'" [treeToRelation]="'id'"
(treeAction)="onTreeAction($event)" (sort)="sortRows($event)" (resize)="resizeTriggered($event)">
<!-- Datatable tree view column -->
<ngx-datatable-column #column_tree_view name="Tree" [isTreeColumn]="true" [width]="150"
[treeLevelIndent]="20">
<ng-template ngx-datatable-tree-toggle let-tree="cellContext">
<button [disabled]="tree.treeStatus==='disabled'" (click)="tree.onTreeAction()">
<span *ngIf="tree.treeStatus==='loading'">
...
</span>
<span *ngIf="tree.treeStatus==='collapsed'">
↑
</span>
<span *ngIf="tree.treeStatus==='expanded'">
↓
</span>
<span *ngIf="tree.treeStatus==='disabled'">
⃠
</span>
</button>
</ng-template>
</ngx-datatable-column>
<ngx-datatable>
I already solved it if someone stomps upon this question:
Firs we define an ng-template on the html of the FacadeTableComponent:
<ng-template #treeTemplate let-row="row">
<div *ngIf="row.IsTreeColumn" class="tree-cell">
<ng-container *ngTemplateOutlet="treeColumnTemplate; context: {row : row}"></ng-container>
<p-button (click)="onTreeAction(row)">
<span *ngIf="row.treeStatus==='collapsed'">
↑
</span>
<span *ngIf="row.treeStatus==='expanded'">
↓
</span>
</p-button>
</div>
After that I just grab the template with the directive viewChild, define a column with the prop value of '_treeColumnName', which is provided as an input of the Facade and unshift it to the columns array:
@ViewChild('treeTemplate') private _treeViewTemplate: TemplateRef<any>;
private createTreeViewColumn(): void {
const column: TableColumn= {
name: this._treeColumnName,
prop: this._treeColumnName,
} as TableColumn;
if (this.columns.findIndex((tablecolumn: TableColumn) => tablecolumn.prop === this._treeColumnName) === -1) {
// the isTreeColumn is not included in the TableColumn, therefore a cast is needed
const tablecolumn = column as TableColumn;
tablecolumn.isTreeColumn = true;
this.columns.unshift(tablecolumn);
}
}
private removeTreeViewColumn(): void {
const treecolumnindex = this.columns.findIndex((tablecolumn: TableColumn) => tablecolumn.prop === this._treeColumnName);
if (treecolumnindex !== -1) {
this.columns.splice(treecolumnindex, 1);
}
}
Finally I just add the implementation to the expand/collapse feature:
private readonly _treeStatusCollapsed: string = 'collapsed';
private readonly _treeStatusExpanded: string = 'expanded';
...
/** Expands or collapses a tree view row
*/
public onTreeAction(event: any): void {
const row = event;
if (row.treeStatus === this._treeStatusCollapsed) {
row.treeStatus = this._treeStatusExpanded;
} else {
row.treeStatus = this._treeStatusCollapsed;
}
// trigger a change detection
this.rows= [...this.rows];
this._changeDetectorRef.detectChanges();
}
And that is it, works like a charm. Of course one could then provida whatever template it wants, or via css classes change the icons.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.