Угловые входные данные, передаваемые асинхронным каналом, имеют значение null в дочернем компоненте, хотя и не являются нулевыми в родительском

У меня странный случай, который я не могу пройти и не знаю, как это происходит, поэтому я получил родительский компонент с именем SiteComponent здесь логика машинописного текста:

ngOnInit(): void {
 this.subs.push(
  this.route.data.subscribe(data => {
    this.siteTemplate$ = this.dataService.getMappedData(`data${data.type}`).pipe(
      map(_data => ({..._data, dataType: data.type })),
      )
   })
 );
}

здесь код файла шаблона:

<div class="app-site">
 <ng-container *ngIf="!siteTemplate$ | async">
    <div fxLayout="row" 
         fxLayoutAlign="center"
         style="margin-top: 60px;">
        <mat-spinner></mat-spinner>
    </div>
 </ng-container>
 <ng-container *ngIf="siteTemplate$ | async">
    <app-filters (filtersChanged)="applyFilters()"></app-filters>
    <div class="app-site-section">
        <div class="app-site-section-column" id="charts">
            <app-linear-chart *ngFor="let record of (siteTemplate$ | async)?.chartsData.records" 
                              [categories]="(siteTemplate$ | async)?.chartsData.categories" 
                              [chartData]="record"
            ></app-linear-chart>
        </div>
        <div class="app-site-section-column">
            <app-pie-chart *ngFor="let record of (siteTemplate$ | async)?.chartsData.records" 
                           [categories]="(siteTemplate$ | async)?.chartsData.categories"
                           [chartData]="record"
            ></app-pie-chart>
        </div>
    </div>
    <div>{{siteTemplate$ | async | json}}</div>
    <div fxLayout="row"
        fxLayoutAlign="center"
        id="table"
        class="app-site-section"
    >
        <app-table [tableData]="(siteTemplate$ | async)?.tableData" 
                   [dataType]="(siteTemplate$ | async)?.dataType"
        ></app-table>
    </div>
 </ng-container>
</div>

как вы можете видеть, он состоит из нескольких дочерних компонентов, которые зависят от асинхронного канала, диаграммы работают отлично, но есть проблема с таблицей.

table.ts

export class TableComponent implements AfterViewInit, OnInit {
  @Input() tableData: any = {records: []};
  @Input() dataType: any;

  dataSource: MatTableDataSource<any> ;

  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;

  constructor() {
  }

  ngOnInit(): void {
    console.log(this.tableData);

    this.dataSource = new MatTableDataSource(this.tableData.records);
  }

  ngAfterViewInit(): void {

    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
  }
}

и здесь я получаю сообщение об ошибке, так как console.log(this.tableData) возвращает значение null, но tableData никогда не имеет значение null в siteTemplate$, поскольку я проверял это, добавляя нажатие и регистрируя это значение, оно всегда отображается как объект.


person Jake11    schedule 27.03.2021    source источник


Ответы (2)


У вас есть несколько siteTemplate$ | async, каждый из которых подпишется на наблюдаемое, поэтому siteTemplate$ | async может быть null. Чтобы предотвратить это, используйте siteTemplate$ | async только один раз:

<ng-container *ngIf="siteTemplate$ | async as siteTemplate; else other">
   ...
   <app-table [tableData]="siteTemplate.tableData" 
                   [dataType]="siteTemplate.dataType"
        ></app-table>
</ng-container>
<ng-template #other>
    <div fxLayout="row" 
         fxLayoutAlign="center"
         style="margin-top: 60px;">
        <mat-spinner></mat-spinner>
    </div>
 </ng-template>
person HTN    schedule 27.03.2021

Используя async-pipe, вы не можете ожидать получения асинхронного результата прямо сейчас, когда созданный дочерний компонент является асинхронным. Итак, следует прослушать результат жизненного цикла ngOnChanges.

  ngOnChanges(): void {
    console.log(this.tableData);

    this.dataSource = new MatTableDataSource(this.tableData.records);
  }
person ClusterH    schedule 27.03.2021