我正在Angular 8中创建父/子关系。Parrent组件调用设置可观察的roleList
的服务调用,然后将该roleList
传递给子组件。在子组件中,我尝试订阅子接收的Input变量,并使用新值实例化MatDataTableSource。
问题是:
子组件接收到该值,但该组件未重新呈现。在我调用应用程序中的更改后(例如:将鼠标悬停在另一个更改状态的组件上),它的确显示了从服务接收到的数据。这些是组件:
父组件.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)); } }
Child Component .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>
编辑:
我在app.component.ts]]中具有ChangeDetectionStrategy.OnPush
。当我将其修改为default时,它将按预期工作。但是,为什么它不适用于onPush?我正在Angular 8中创建父/子关系。Parrent组件调用服务调用,该服务调用设置了可观察的roleList,然后将该角色列表传递给child组件。在子组件中,我...
这是因为您正在通过合并this.sort.sortChange和this.paginator.page来创建一个可观察对象,然后订阅该可观察对象并更新mat表数据。这意味着,只要排序或分页发生变化,observable就会发出一个值,并且表将在订阅中更新。但是,无法处理您可观察到的数据中发出的任何值。
解决方案: