问题
There's quite good doc of using *ngIf in Angular: https://angular.io/api/common/NgIf But, is that possible to have *ngIf async variable and multiple checks on that? Something like:
<div *ngIf="users$ | async as users && users.length > 1">
...
</div>
Of course, it's possible to use nested *ngIf, like:
<div *ngIf="users$ | async as users">
<ng-container *ngIf="users.length > 1">
...
</ng-container>
</div>
but it'd be really nice to use only one container, not two.
回答1:
Simply do it like this
<div *ngfor="let user of users$ | async" *ngIf="(users$ | async)?.length > 1">...</div>
For "more complex" scenario do the following
<div *ngfor="let user of users$ | async" *ngIf="(users$ | async)?.length > 1 && (users$ | async)?.length < 5">...</div>
Edit: Previous wouldn't work since you cannot use *ngFor
and *ngIf
without using ng-template. You would do it like that for instance
<ng-template ngFor let-user [ngForOf]="users$ | async" *ngIf="(users$ | async)?.length > 1 && (users$ | async)?.length < 5">
<div>{{ user | json }}</div>
</ng-template>
Here is a stackblitz.
回答2:
I hit the same issue of needing an *ngIf + async variable with multiple checks.
This ended up working well for me.
<div *ngIf="(users$ | async)?.length > 0 && (users$ | async) as users"> ... </div>
or if you prefer
<div *ngIf="(users$ | async)?.length > 0 && (users$ | async); let users"> ... </div>
Explanation
Since the result of the if expression is assigned to the local variable you specify, simply ending your check with ... && (users$ | async) as users
allows you to specify multiple conditions and specify what value you want the local variable to hold when all your conditions succeed.
Note
I was initially worried that using multiple async
pipes in the same expression may create multiple subscriptions, but after some light testing (I could be wrong) it seems like only one subscription is actually made.
回答3:
Here's the alternative version, with a little bit cleaner template:
<ng-template [ngIf]="(users$ | async)?.length > 1" [ngIfElse]="noUsersMessage">
<div *ngFor="let user of (users$ | async)">{{ user | json }}</div>
</ng-template>
<ng-template #noUsersMessage>No users found</ng-template>
Note that we use users$ | async
2 times. That will work if you add shareReplay() operator to user$
Observable:
public users$: Observable<any[]> = this.someService.getUsers()
.pipe(shareReplay());
That way, inner template will be able to access last value of the Observable and display the results.
You can try it out on stackblitz.
来源:https://stackoverflow.com/questions/49296784/angular-ngif-variable-with-async-pipe-multiple-conditions