Is it possible to set the CompareWith function of Angular SelectionModel object in TypeScript

Viewed 984

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);
      }
   }  
1 Answers

So, having examined the source, it doesn't seem possible to sub-class the SelectionModel to replace the method used for comparing objects. This is because most of the properties of the SelectionModel are declared as private in the TypeScript. I suppose that this could all be ignored & overridden since it's basically JS underneath, but the compiler complains when I tried to work with them - and I like keep a clean compilation.

What I have done is create a new class without any inheritance form SelectionModel. This class implements my required subset of SelectionModel (toggling items in the selection, and emitting events when changes happen) - with the capability I needed to supply a function for comparing objects, and use this one instead of the Collections/SelectionModel class. The cast is a bit messy, but it prevents the compiler moaning!

this.selectionModel= <SelectionModel<InputOptionIf>><unknown>new MySelectionMode(...)

Its working now, and that's all I needed. Thanks for the pointers.

Related