I have a dynamic data table build using Angular Material where I am using an API to supply the table with data currently.
I want to use add a checkbox column to select a specific row, and/or multiple rows, but I'm having an issue with showing the checkbox row in order to make a selection.
Right now my row of checkboxes is not appearing at all. the first ng-container column is not showing
and I'm not sure what's the issue?
I'm using Angular 7 with Angular Material
view.component.html
<table mat-table [dataSource]="fetchedData" matSort matSortActive="{{defaultSortCol}}" matSortDirection="asc">
<ng-container matColumnDef="select">
<th mat-header-cell *matHeaderCellDef style="width:40px;">
<mat-checkbox (change)="$event ? masterToggle() : null"
[checked]="selection.hasValue() && isAllSelected()"
[indeterminate]="selection.hasValue() && !isAllSelected()">
</mat-checkbox>
</th>
<td mat-cell *matCellDef="let row">
<mat-checkbox (click)="$event.stopPropagation()" (change)="$event ? selection.toggle(row) : null"
[checked]="selection.isSelected(row)">
</mat-checkbox>
</td>
</ng-container>
<ng-container [matColumnDef]="column.columnId" *ngFor="let column of viewData.ColumnObjects">
<th mat-header-cell *matHeaderCellDef mat-sort-header>
{{ column.propertyName }}
</th>
<td mat-cell *matCellDef="let action">{{ action[column.columnId] }}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="viewData.ColumnIds; sticky: true"></tr>
<tr mat-row *matRowDef="let row; columns: viewData.ColumnIds"></tr>
</table>
view.component.ts
@Component({
templateUrl: 'viewpage.component.html'
})
export class ViewpageComponent implements AfterViewInit, OnInit, OnDestroy {
viewData: any;
viewName: string;
viewTag: number;
fetchedData: any;
dataSource: ViewData
Source;
pageSizeOptions: number[] = [10, 20, 50];
defaultSortCol = "1";
@ViewChild(MatSort) sort: MatSort;
@ViewChild(MatPaginator) paginator: MatPaginator;
selection = new SelectionModel<TableRow>(true, []);
navSub: any;
constructor(private actionService: ActionService, private route: ActivatedRoute, private router: Router) { }
ngOnInit() {
// Init the component the first time it is navigated to.
this.initData();
// Subscribe to the router, so that any new navigation to this component loads new data.
this.navSub = this.router.events.subscribe((e: any) => {
if(e instanceof NavigationEnd){
this.initData();
}
});
}
initData(){
this.viewTag = +this.route.snapshot.paramMap.get("tag");
this.dataSource = new ViewDataSource(this.actionService);
// Load the View from the DataSource with default params
this.dataSource.loadView(this.viewTag, 0, 10, this.defaultSortCol, "asc");
// Subscribe to the View in the DataSource
this.dataSource.view.subscribe(x => {
if (x.ActionName) {
this.viewName = x.ActionName;
this.viewData = x;
this.fetchedData = this.viewData.TableData;
console.log(`View Data ` + JSON.stringify(this.viewData.ViewData.DbrAction));
// this.viewData = ['select'].concat(this.viewData);
}
});
}
ngAfterViewInit() {
// After sorting, jump back to first page of newly sorted data.
this.sort.sortChange.subscribe(
() => {
this.paginator.pageIndex = 0
});
// Sort changes and pagination events should reload the page.
merge(this.sort.sortChange, this.paginator.page)
.pipe(
tap(() => this.loadPage())
).subscribe();
}
loadPage() {
this.dataSource.loadView(
this.viewTag,
//'',
this.paginator.pageIndex,
this.paginator.pageSize,
this.sort.active,
this.sort.direction);
}
Your table try's to use viewdata
before it is initial set, in fact viewData
is undefined.
Thats why viewData.ColumnObjects
throws an TypeError
.
Try to use ?
check eg viewData?.ColumnObjects
or guard your table with *ngIf="viewData"
...
<ng-container [matColumnDef]="column.columnId" *ngFor="let column of viewData?.ColumnObjects">
...
You mentioned a 'row' of checkboxes a few times, but it looks like you're trying to add a column of checkboxes, which makes sense given your requirement of selecting items in the table.
Does viewData.ColumnIds have 'select' in it? If not, that's your problem. The material table doesn't render every matColumnDef you give it, it only renders the matColumnDefs that have matching names in the 'columns' array.
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.