Angular 5 показывает «Данные не найдены» при пустых результатах

1

Я использую 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>

Итак, каков правильный способ достижения этого? Благодарю.

  • 0
    <ion-card *ngIf="filter != 'all' && filter != r.confirmed"> <ion-item> No Data </ion-item> </ion-card>
  • 0
    Попробуйте переместить <ng-template #empty> внутрь списка ионов
Показать ещё 5 комментариев
Теги:
angular
angular-ng-if

2 ответа

0
Лучший ответ

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;
}
  • 0
    Это кажется разумным подходом. Я постараюсь преобразовать ваш код (я использую Angularfire2 и Firebase) и посмотрю, работает ли он.
  • 0
    Это действительно может быть улучшено путем использования некоторых более продвинутых методов (компонент представления + включение); Вы можете сбросить пустой $ и ng-if-else. Если вы заинтересованы в этом, дайте мне знать, чтобы я мог обновить ответ.
Показать ещё 1 комментарий
1

Попробуйте этот подход и скажите, работает ли он для вас.

Составная часть:

// 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>

Итак, моя идея заключается в том, что сначала мы проверяем, стоит ли цитировать данные в шаблоне. Мы проверяем это в компоненте, видим, существует ли какое-либо резервирование с отфильтрованными значениями.

Если он не существует, мы не будем цитировать, мы просто показываем (без данных). Если это действительно существует, мы будем циклически и печатать их...

Это имеет смысл? Надеюсь, это поможет вам или, по крайней мере, указывает на правильное направление!

  • 0
    спасибо, я думаю, это сработает, но решил пойти с @ Jota.Toledo, потому что очень большой список может работать лучше с его кодом
  • 0
    @fana Все хорошие люди! Я рад, что вы нашли решение! ;)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню