I'm using Angular 5 and I'm building a list of items with some buttons that filter the list. What I'm struggling to do is show a "No data found" kind of message when one of those filters hide every item of the list.
It's basically this:
The filter buttons
<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>
The list
<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>
Note: I'm using the async pipe because data es from Firebase Realtime Database.
So, all my items are in a state of pending (having confirmed: 2), so when I click on the Confirmed button, all the items on the list get hidden, which is perfect. But how can I show a "No data found" message instead of an empty list?
I've tried the else condition, but I'm getting multiple "No data found" messages (one for each hidden item):
<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>
So what's the correct way of achieving this? Thanks.
I'm using Angular 5 and I'm building a list of items with some buttons that filter the list. What I'm struggling to do is show a "No data found" kind of message when one of those filters hide every item of the list.
It's basically this:
The filter buttons
<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>
The list
<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>
Note: I'm using the async pipe because data es from Firebase Realtime Database.
So, all my items are in a state of pending (having confirmed: 2), so when I click on the Confirmed button, all the items on the list get hidden, which is perfect. But how can I show a "No data found" message instead of an empty list?
I've tried the else condition, but I'm getting multiple "No data found" messages (one for each hidden item):
<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>
So what's the correct way of achieving this? Thanks.
Share Improve this question asked Feb 13, 2018 at 13:34 fanafana 3737 silver badges19 bronze badges 7-
<ion-card *ngIf="filter != 'all' && filter != r.confirmed"> <ion-item> No Data </ion-item> </ion-card>
– mast3rd3mon Commented Feb 13, 2018 at 13:37 - Try moving <ng-template #empty> inside of the ion-list – Boris Lobanov Commented Feb 13, 2018 at 13:37
- @mast3rd3mon That way it gives me duplicated "No Data", one for each hidden list item... – fana Commented Feb 13, 2018 at 14:02
- @BorisLobanov Yes, I've tried that but the result is the same... – fana Commented Feb 13, 2018 at 14:03
-
This is not a good use case for
else
. Just use<div *ngIf ="(reservations | async).filter(f)">None</div>
– Aluan Haddad Commented Feb 13, 2018 at 14:17
2 Answers
Reset to default 3IMO you shouldnt display the raw list of reservations. Instead, display the already filtered list:
ponent.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>
ponent.ts
import {bineLatest} from 'rxjs/observable/bineLatest';
import {FormControl} from '@angular/forms';
status= new FormControl;
reservations$: Observable<IReservation[]>;
empty$: Observable<boolean>;
constructor(){
this.reservations$ = bineLatest(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;
}
Try this approach and tell me if it works for you.
Component:
// 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;
}
Template:
<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>
So, my idea is that first we check if it's worth to loop through the data in the template. We check this in the ponent, we see if it exists any reservation with the filtered values.
If it doesn't exist, we won't loop, we just display (no data). If it does exist though, we'll loop and print them...
Does it makes sense? Hope it helps you or at least points you to the right direction!
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745251392a4618697.html
评论列表(0条)