We have a material data table with the colums id
and Decription
.
We want to have two mat-checkbox
fields, one for id
and one for description
that when clicked hide the corresponding column in the data table.
Approach
We’ll use a columnsDefinitions
object to define which column definitions are hidden:
columnDefinitions = [
{ def: 'id', hide: this.cb1.value},
{ def: 'description', hide: this.cb2.value}
]
The RxJS merge operator is used to observe the mat-checkbox
fields and update the columnDefinitions:
let o1:Observable<boolean> = this.cb1.valueChanges;
let o2:Observable<boolean> = this.cb2.valueChanges;
merge(o1, o2).subscribe( v=>{
this.columnDefinitions[0].hide = this.cb1.value;
this.columnDefinitions[1].hide = this.cb2.value;
console.log(this.columnDefinitions);
});
}
Finally we’ll filter the columnDefinitions
to get the columns we want to display:
getDisplayedColumns():string[] {
return this.columnDefinitions.filter(cd=>!cd.hide).map(cd=>cd.def);
}
And we’ll use getDisplayedColumns
in our template like this:
<mat-header-row *matHeaderRowDef="getDisplayedColumns()">
</mat-header-row>
<mat-row *matRowDef="let row; columns: getDisplayedColumns()"></mat-row>
Demo
Simpler Demo
This demo is shorter. It uses a displayedColumns$:Observable<string[]>
to display the columns.
This should be better from a performance point of view, since the getDisplayedColumns()
function will not be called on all state changes.