Я создаю отношения Parent / Child в Angular 8. Компонент Parrent вызывает сервисный вызов, который устанавливает наблюдаемое roleList
, затем я передаю этот roleList
дочернему компоненту. В дочернем компоненте я пытаюсь подписаться на переменную Input, которую получает дочерний элемент, и создаю экземпляр MatDataTableSource с новыми значениями.
Проблема заключается в следующем: Дочерний компонент получает значение, но компонент не-render. После того, как я вызываю изменение в приложении (например, при наведении мыши на другой компонент, который изменяет состояние), в нем отображаются данные, полученные от службы.
Это компоненты:
Родительский компонент .ts:
import { Component, OnInit, ChangeDetectionStrategy } from
'@angular/core';
import { RoleService } from '../role.service';
import { RoleTemplateList } from '../../../../core/models/role-template-
list.model';
import { Observable } from 'rxjs';
@Component({
selector: 'kt-view-roles',
templateUrl: './view-roles.component.html',
styleUrls: ['./view-roles.component.scss'],
})
export class ViewRolesComponent implements OnInit {
roleList: Observable<RoleTemplateList[]>;
columns = ['id', 'name', 'skills', 'actions'];
actions = ['actions'];
constructor(private roleService: RoleService) {}
ngOnInit() {
this.roleList = this.roleService.getRoles();
}
}
Родительский компонент .html:
<kt-portlet-header [class]="'kt-portlet__head--lg'">
<ng-container ktPortletTitle>
<h3 class="kt-portlet__head-title">
<span>All Roles</span>
</h3>
</ng-container>
</kt-portlet-header>
<kt-portlet-body>
<kt-data-table-new [columnsToDisplay]="columns" [data]="roleList"></kt-data-table-new>
</kt-portlet-body>
</kt-portlet>
Это компонент, который я пытаюсь подписать и инициализироватьMatTableDataSource с результатом подписки.
Дочерний компонент .ts:
import { Component, OnInit, Input, AfterViewInit, ViewChild, OnChanges,
ChangeDetectionStrategy } from '@angular/core';
import { Observable, merge, of } from 'rxjs';
import { MatPaginator, MatSort, MatTableDataSource } from
'@angular/material';
import { startWith, switchMap, map, catchError, filter, tap } from
'rxjs/operators';
@Component({
selector: 'kt-data-table-new',
templateUrl: './data-table-new.component.html',
styleUrls: ['./data-table-new.component.scss']
})
export class DataTableNewComponent implements AfterViewInit {
@Input() columnsToDisplay: any[];
@Input() data: Observable<any[]>;
dataSource: MatTableDataSource<any>;
isLoadingResults = true;
dataLength = 0;
@ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;
@ViewChild(MatSort, {static: true}) sort: MatSort;
constructor() { }
ngAfterViewInit() {
this.sort.sortChange.subscribe(() => this.paginator.pageIndex= 0);
merge(this.sort.sortChange, this.paginator.page)
.pipe(
startWith({}),
switchMap(() => {
this.isLoadingResults = true;
return this.data;
}),
map(data => {
this.isLoadingResults = false;
this.dataLength = data.length;
return data;
}),
catchError(() => {
this.isLoadingResults = false;
return of([]);
}),
).subscribe(value => this.dataSource = new MatTableDataSource(value));
}
}
Дочерний компонент .html:
<div class="example-container mat-elevation-z8">
<div class="example-loading-shade" *ngIf="isLoadingResults">
<mat-spinner *ngIf="isLoadingResults"></mat-spinner>
</div>
<div class="example-table-container">
<table mat-table [dataSource]="dataSource" class="example-table" matSort matSortActive="created"
matSortDisableClear matSortDirection="desc">
<ng-container [matColumnDef]="column" *ngFor="let column of columnsToDisplay">
<th mat-header-cell *matHeaderCellDef>
{{column}}
</th>
<td mat-cell *matCellDef="let element"> {{element[column]}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
<tr mat-row *matRowDef="let row; columns: columnsToDisplay;"></tr>
</table>
</div>
<mat-paginator [length]="dataLength" [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator>
Редактировать:
У меня есть ChangeDetectionStrategy.OnPush в app.component.ts . Когда я изменяю его на по умолчанию , он работает как положено. Но почему это не работает с onPush?