角形异步管道和对象属性

我需要使用不带 ngFor 的异步管道。我需要检查对象的属性是异步加载与观察。

这就是我想要的,但是不起作用:

 <ion-item *ngIf="user$.anonymouse | async">
<ion-label>Login</ion-label>
</ion-item>

//编辑: 当我使用上面的代码时,我得到了这个错误

例外: 在[ ! user $. onymous ouse | sync in SettingsPage@27:22]中,管道‘ AsyncPipe’的无效参数‘ true’

有办法解决吗?

我知道我可以订阅这个观察在 Ctrl 一个存储值到正常变量,但我不想这样做,因为性能等。

65075 次浏览

The error is surprisingly accurate as the *ngIf directive expects true or false and uses the resulting expression to determine whether or not to render the HTML element in the DOM.

EXCEPTION: Invalid argument 'true' for pipe 'AsyncPipe' in [!user$.anonymouse | async in SettingsPage@27:22]

The expression you have is user$.anonymouse which evaluates as truthy, but unfortunately you cannot use the async pipe with this directive. The async pipe "transforms" (also known as "pipes") the input exposing the resulting output within the scope of the *ngFor directive for example.

The pipe expects one of three possible types, defined below (detailed about AsyncPipe):

transform(obj: Observable<any>| Promise<any>| EventEmitter<any>)

Is there any way how to solve this?

Yes, you can either use it as it was designed. For example in an *ngFor directive:

<ion-item *ngFor="(user$ | async)?.anonymouse">
<ion-label>Login</ion-label>
</ion-item>

Or you could remove the piping altogether as it's not needed for the *ngIf directive:

<ion-item *ngIf="user$.anonymouse">
<ion-label>Login</ion-label>
</ion-item>

As stated in the comments by @Sean, your *ngIf statement should be based on the resulted object property anonymouse of the user$ object that is returned. As such:

<ion-item *ngIf="(user$ | async)?.anonymouse">
<ion-label>Login</ion-label>
</ion-item>

This worked for me and here is an example of how to use the results from the pipe below:

Component

 message$: Observable<{message: string}>;


private messages = [
{message: 'You are my hero!'},
{message: 'You are the best hero!'},
{message: 'Will you be my hero?'}
];


constructor() { this.resend(); }


resend() {
this.message$ = Observable.interval(500)
.map(i => this.messages[i])
.take(this.messages.length);
}

View

<h2>Async Hero Message and AsyncPipe</h2>
<p>Message: \{\{ (message$ | async)?.message }}</p>
<button (click)="resend()">Resend</button>`

A working example can be found here.

<!-- This is needed to wait for async pipe to resolve -->
<div *ngIf="user$ | async as user">


<!-- Only on resolve of async pipe -->
<ion-item *ngIf="user.whateverPropertyYouWantToCheck">
<ion-label>Login</ion-label>
</ion-item>
</div>

Please note that I switched from user$ to user, you can use the same variable name if you want to, but this makes it more clear that the value is no longer an async pipe.

isAnonymouse$ = user$.pipe(map(user => user?.anonymouse));

<ion-item *ngIf="user$.anonymouse | async">