Я использую Angular 5, и я создаю список элементов с некоторыми кнопками, которые фильтруют список. То, что я пытаюсь сделать, это показать сообщение "Нет данных", когда один из этих фильтров скрывает каждый элемент списка.
Это в основном это:
Кнопки фильтра
<div padding>
<ion-segment [(ngModel)]="filter" (ionChange)="onFilterChange()">
<ion-segment-button value="all">
All
</ion-segment-button>
<ion-segment-button value="2">
Pending
</ion-segment-button>
<ion-segment-button value="1">
Confirmed
</ion-segment-button>
</ion-segment>
</div>
Список
<ion-list *ngFor="let r of (reservations | async)">
<ion-card *ngIf="(filter == 'all' || filter == r.confirmed)">
<ion-item>
Item
</ion-item>
</ion-card>
</ion-list>
Примечание. Я использую async-канал, потому что данные поступают из базы данных Firebase Realtime.
Итак, все мои объекты находятся в состоянии ожидания (подтвердив: 2), поэтому, когда я нажимаю кнопку "Подтвержденный", все элементы в списке спрятаны, что идеально. Но как я могу показать сообщение "Нет данных" вместо пустого списка?
Я пробовал условие else, но я получаю несколько сообщений "Нет данных" (по одному для каждого скрытого элемента):
<ion-list *ngFor="let r of (reservations | async)">
<ion-card *ngIf="(filter == 'all' || filter == r.confirmed); else empty;">
<ion-item>
Item
</ion-item>
</ion-card>
</ion-list>
<ng-template #empty>
No data found...
</ng-template>
Итак, каков правильный способ достижения этого? Благодарю.
IMO вы не должны отображать необработанный список резервирования. Вместо этого отобразите уже отфильтрованный список:
component.html
<ion-segment [formControl]="status" (ionChange)="onFilterChange()">
<ion-segment-button value="2">
Pending
</ion-segment-button>
<ion-segment-button value="1">
Confirmed
</ion-segment-button>
</ion>
<div *ngIf="empty$ | async; else notEmpty">
Nothing
</div>
<ng-template #notEmpty>
<ion-list *ngFor="let reservation of reservations$ | async">
<ion-card>
<ion-item>
Item
</ion-item>
</ion-card>
</ion-list>
</ng-template>
component.ts
import {combineLatest} from 'rxjs/observable/combineLatest';
import {FormControl} from '@angular/forms';
status= new FormControl;
reservations$: Observable<IReservation[]>;
empty$: Observable<boolean>;
constructor(){
this.reservations$ = combineLatest(rawReservations$,this.status.valueChanges,this._applyFilter);
this.empty$ = this.reservations$.map(reservations => reservations.length === 0);
}
private _applyFilter(reservations: IReservation[], status: number): IReservation[]{
let result = reservations;
//apply filter logic
return result;
}
Попробуйте этот подход и скажите, работает ли он для вас.
Составная часть:
// control variable
dataAvailable = false;
onFilterChange(filterType: number) {
// your code and logic
// This is pretty ugly, make it prettier please...
// checking if exists at least 1 reservation with confirmed = 1 | 2 (depends on argument).
this.dataAvailable = this.reservations.filter(res => res.confirmed === filterType).length > 0;
}
Шаблон:
<div *ngIf="dataAvailable; then printData else empty"></div>
<ng-template #printData>
<ion-list *ngFor="let r of (reservations | async)">
<ion-card>
<ion-item>
Item
</ion-item>
</ion-card>
</ion-list>
</ng-template>
<ng-template #empty>
No data found...
</ng-template>
Итак, моя идея заключается в том, что сначала мы проверяем, стоит ли цитировать данные в шаблоне. Мы проверяем это в компоненте, видим, существует ли какое-либо резервирование с отфильтрованными значениями.
Если он не существует, мы не будем цитировать, мы просто показываем (без данных). Если это действительно существует, мы будем циклически и печатать их...
Это имеет смысл? Надеюсь, это поможет вам или, по крайней мере, указывает на правильное направление!
<ion-card *ngIf="filter != 'all' && filter != r.confirmed"> <ion-item> No Data </ion-item> </ion-card>