I have a component that renders mat-table in it's template. I want to pre-select some of the rows. The SelectionModel I have contains objects representing each selected item (not simple strings or numbers) and the method for comparing these is more complex than the native SelectionModel's method.
If this was a mat-select form control, I could use the [compareWith] directive to supply a custom comparison function e.g.
<mat-select [compareWith]="myCompareFunction" >...
but this is not suitable solution - as I need a tabular presentation. I an following closely the example in the Angular documents. The mat-table examples here: have a mat-table with selection checkbox on each row and this is the approach I have followed.
In the example's Component code it uses a SelectionModel object.
import {SelectionModel} from '@angular/cdk/collections';
....
....
selection = new SelectionModel<PeriodicElement>(true, []);
I am searching for a way to supply a custom comparison function to the SelectionModel object. Can SelectionModel be sub-classed with an override for the function or can a method be 'injected' in some way?
I have tried to sub-class SelectionModel and declare a new compareWith function, but this doesn't seem to be what's required. Can anyone advise?
import { SelectionModel } from '@angular/cdk/collections';
import { InputOptionIf } from '../formosa-interfaces/dynamic-field-config-if';
export class ModalSelectSelectionModel extends SelectionModel<InputOptionIf>{
compareWith(o1:any,o2:any) {
console.log("ModalSelectSelectionModel.compareWith()")
return( <InputOptionIf>o1.label==<InputOptionIf>o2.label);
}
}
If you are stuck on angular <14 you can extend SelectionModel and override the
isSelectedmethod. In the CDK implementation SelectionModel uses a Set to store the selection and they check if an item is contained in that set by usingSet.has. Thankfully the only place whereSet.hasis called is inisSelected. Everywhere else in the class usesisSelectedto check if the item already exists.You should also override the deselect method to first find the value in the selection using the compareWith function. This ensures that the value being deselected is the same instance as the value in the set. Without this some values may not get deselected as expected.
Here is an example implementation which accepts a compareWith function in the same way the angular 14 implementation works. When you upgrade to angular 14 you should be able to simply replace ComparableSelectionModel with SelectionModel.