4

I'm learning about angular ViewChild currently, but I seem to be missing something when using ViewChild to select custom reference variables from the DOM.

In my template I have two tables:

<mat-table #eventTable [dataSource]="eventDataSource" matSort>
<mat-table #eventDateTable [dataSource]="dateEventDataSource" matSort>

I am attempting to target them with a sort for each:

@ViewChild('eventTable') eventTableSort: MatSort;
@ViewChild('eventDateTable') eventDateTableSort: MatSort;

Then I attempt to initiate them in ngAfterViewInit():

this.eventDataSource.sort = this.eventTableSort;
this.dateEventDataSource.sort = this.eventDateTableSort;

The result is nothing happens on either table when I click the headers to sort each column. I'm sure there is something simple I am overlooking here but I can't see what it is. How can I make each of these tables sort independently of each other?

Broc Broccoli
  • 191
  • 3
  • 11
  • Are you sure you are dealing with `angularjs` and not `angular` and `angular-material` and `angular-material2` ? Your code looks like `angular` constructs (currently version 5.x) – bhantol Jan 23 '18 at 15:47
  • @bhantol whoops I used the wrong tags, fixed now. Thanks! – Broc Broccoli Jan 23 '18 at 15:55

1 Answers1

4

I had been attempting to follow this question to derive and answer but it wasn't making sense to me. So I dove into a debugger and found an answer to my question.

When declaring a reference variable (#eventTable and #eventDateTable) you are creating a reference to the element/component/directive that you have declared it on. In my example I was creating a reference to each <mat-table> I had created. I was then attempting to assign these tables themselves to the eventTableSort and eventDateTableSort values. In ngAfterViewInit() I was essentially saying to set the sort for each dataset equal to the table it's stored in.

The correct way to go about targeting the MatSort for each table is to declare it when setting your reference variables. Rather than #eventTable which will create a reference for the whole table, #eventTable="matSort" will create a reference directly to that table's MatSort object. Then in your component you can use a ViewChild to target the MatSort itself.

Here are the same code I have written above now working correctly:

<mat-table #eventTable="matSort" [dataSource]="eventDataSource" matSort>
<mat-table #eventDateTable="matSort" [dataSource]="dateEventDataSource" matSort>

@ViewChild('eventTable') eventTableSort: MatSort;
@ViewChild('eventDateTable') eventDateTableSort: MatSort;

this.eventDataSource.sort = this.eventTableSort;
this.dateEventDataSource.sort = this.eventDateTableSort;
Broc Broccoli
  • 191
  • 3
  • 11