Как показать пустое сообщение в динамической таблице угловых данных

Я пытаюсь показать пустое сообщение об ошибке, когда фильтр не соответствует:

<div *ngIf="dataSource.length === 0">No data</div>

но это не работает, потому что я строю динамическую таблицу с MatTableDataSource.

Для лучшего понимания я изменил свою динамическую таблицу на предопределенный массив.

const ELEMENT_DATA: MembersElement[] = [
{ name: 'Jenny', age: 17 },
{ name: 'Daniel', age: 18 }
];

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

Это весь мой код TS.

    import { Component, OnInit } from '@angular/core';
import {MatTableDataSource} from '@angular/material';

export interface SociosElement {
  nombre: string;
  edad: number;
}

const ELEMENT_DATA: MembersElement[] = [
  { name: 'Jenny', age: 17 },
  { name: 'Daniel', age: 18 }
];

@Component({
  selector: 'app-pruebas',
  templateUrl: './tableMembers.component.html',
  styleUrls: ['./tableMembes.component.css']
})
export class PruebasComponent {
  displayedColumns: string[] = ['name', 'age'];
  dataSource = new MatTableDataSource(ELEMENT_DATA);

  applyFilter(filterValue: string) {
    this.dataSource.filter = filterValue.trim().toLowerCase();
  }
}

Это мой HTML-код.

<mat-toolbar color="primary">My full table</mat-toolbar>
<mat-form-field>
    <input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
</mat-form-field>
<mat-table #table [dataSource]="dataSource">
    <ng-container matColumnDef="name">
        <mat-header-cell *matHeaderCellDef mat-sort-header>Name </mat-header-cell>
        <mat-cell *matCellDef="let element"> {{element.name}} </mat-cell>
    </ng-container>
    <ng-container matColumnDef="age">
        <mat-header-cell *matHeaderCellDef mat-sort-header>Age </mat-header-cell>
        <mat-cell *matCellDef="let element"> {{element.age}} </mat-cell>
    </ng-container>
    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns;" (click)="row.toggle(row)">
    </mat-row>
</mat-table>
<div *ngIf="dataSource.length === 0">No data</div>

1 ответ

Решение

Вы не можете достичь того, что вы хотите, используя *ngIf="dataSource.length === 0" просто потому, что источник данных вообще не меняется при фильтрации. что вам нужно сделать, это следить за длиной отфильтрованных данных. Вы можете использовать что-то вроде следующего:*ngIf="dataSource.filteredData.length > 1" как условие. длина datasource.filteredData изменяется на основе отфильтрованных результатов. это условие может скрыть ваш стол. Вы можете поместить это в свой тег таблицы как: <table mat-table [dataSource]="dataSource" *ngIf="dataSource.filteredData.length > 1">

Одно предостережение об использовании ngIf. Если вы используете matSort и вкладываете таблицу в блок, используя * ngIf, то сортировка не будет работать, потому что ngIf устанавливает viewChild в значение undefined. Ссылка

Используйте [ngClass], чтобы обойти это

<div [ngClass]="dataSource.filteredData.length > 0 ? 'visible': 'hidden'">
  <mat-table #table [dataSource]="dataSource" matSort>
    <ng-container matColumnDef="name">
      <mat-header-cell *matHeaderCellDef mat-sort-header>Name </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.name}} </mat-cell>
    </ng-container>
    <ng-container matColumnDef="age">
      <mat-header-cell *matHeaderCellDef mat-sort-header>Age </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.age}} </mat-cell>
    </ng-container>
    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns;" (click)="row.toggle(row)">
    </mat-row>
  </mat-table>
</div>
<div [ngClass]="dataSource.filteredData.length > 0 ? 'hidden': 'visible'">
  <tr>No results found.</tr>
</div>

Вот CSS для классов

.hidden {
  visibility: hidden;
}

.visible {
  visibility: visible;
}

Для mat-table до v10 вы могли дать таблице строку данных, когда ваш dataSource пуст, выполнив следующие действия:[dataSource]="dataSource.data.length > 0 && dataSource.data.filteredData > 0 ? dataSource : emptyDataSource"Затем создайте столбец def для вашей ячейки, чтобы отобразить пустое сообщение данных:<ng-container vdlColumnDef="empty-row"> <td *matCellDef="let row" mat-cell [colSpan]="displayedColumns.length">No Data</td> </ng-container>Затем измените свою строку def, чтобы отображать пустой столбец строки def, когда dataSource пуст:<tr mat-row *matRowDef="let row; columns: dataSource.data.length > 0 && dataSource.data.filteredData > 0 ? displayedColumns : ['empty-row'];">

https://stackblitz.com/edit/angular-mat-table-no-data?file=src%2Fapp%2Ftable-basic-flex-example.html

После Angular Material 10 они добавили директиву для случаев, когда в таблице нет данных: "Если вы хотите показать сообщение, когда данные не соответствуют фильтру, вы можете использовать директиву *matNoDataRow". https://v10.material.angular.io/components/table/overview#filtering

Другие вопросы по тегам