Здесь есть несколько проблем с синхронизацией жизненного цикла, и если подумать, это правильно.
MatSort является частью представления, поэтому он не «готов» во время OnInit - он не определен. Так что попытка его использования приводит к ошибке.
MatSort готов в AfterViewInit, но все усложняется тем фактом, что вам необходимо «применить» сортировку к источнику данных после выполнения сортировки, и это вызывает изменения в представлении с помощью RenderedData, которая является ' подключен к источнику данных. В результате вы получаете ExpressionChangedAfterItHasBeenCheckedError, поскольку жизненный цикл инициализации представления не завершен, но вы уже пытаетесь изменить его.
Таким образом, вы не можете выполнить сортировку, пока представление не будет готово, и вы не сможете применить сортировку, когда получите уведомление о том, что представление готово. Единственное, что вы можете сделать, это дождаться окончания жизненного цикла инициализации компонента. И вы можете сделать это с помощью setTimeout ().
Я не думаю, что есть какой-либо способ обойти обе эти проблемы без setTimeout (), поэтому в этом случае не имеет значения, вызываете ли вы его из OnInit или AfterViewInit.
Пара других замечаний по вашему коду:
Вам не нужно создавать новый экземпляр MatTableDataSource в вашей подписке. Вы можете присвоить данные результатов уже созданному источнику данных:
this.dataSource.data = myData;
Это освобождает вас от необходимости впоследствии подключать отображаемые данные к источнику данных, так что вы можете сделать это при инициализации источника данных:
dataSource: MatTableDataSource<any> = new MatTableDataSource();
renderedData: Observable<any> = this.dataSource.connect();