首页 > 解决方案 > Socket.io 和 Angular 使用异步管道

问题描述

我有个问题。我发现了很多异步管道需要 Observables 的信息。所以,我认为我在 socket.on 事件上从我的服务返回 observable,但似乎我错了。我应该如何正确实施?

服务:

public getUsers(): Observable<any> {
    return new Observable<any>(observer => {
        this.socket.on('my_users', (data) => observer.next(data));
    });
}

零件:

users: Observable<any[]>;

this.http.getUsers().subscribe((user: any) => {
    this.users = user.data;
});

模板:

<button class="send_to_username" 
        value="{{user}}" 
        *ngFor='let user of users;  let i = index' 
        [ngClass]="{'active':isClicked[i]}"
        (click)="isClicked[i] = (isClicked[i]? false :true); getReceiver(user)"
>{{user | async}}</button>

服务器:

@socketio.on('username', namespace='/private')
def receive_username(username):
users[username] = request.sid
print('Username added!')
print(users)
emit('my_users',
     {'data': list(users.keys())})

ERROR 错误:“InvalidPipeArgument:管道‘AsyncPipe’的‘111111’”

标签: angulartypescriptsocket.io

解决方案


你声明users为一个 Observable。但它被初始化为其他东西,即你的数据。

// This part is a subscription to an observable:
this.http.getUsers().subscribe((user: any) => {
    // This part is just a regular assignment:
    this.users = user.data;
});

所以这一行是错误的:users: Observable<any[]>;

相反,它应该是这样的:users: Array<any> = []

您的错误实际上是由于其他原因。您错误地使用了异步管道。

<button
    class="send_to_username"
    value="{{user}}"
    *ngFor='let user of users; let i = index'
    [ngClass]="{'active':isClicked[i]}"
    (click)="isClicked[i] = (isClicked[i]? false :true); getReceiver(user)"> 
    {{user | async}}
</button>

应该:

<button
    class="send_to_username"
    value="{{user}}"
    *ngFor='let user of users; let i = index'
    [ngClass]="{'active':isClicked[i]}"
    (click)="isClicked[i] = (isClicked[i]? false :true); getReceiver(user)"> 
    {{user}}
</button>

但是,如果您想通过管道输出 Observable 的输出,则可以删除所有这些:

users: Observable<any[]>;

this.http.getUsers().subscribe((user: any) => {
    this.users = user.data;
});

而只是写:

<button
    class="send_to_username"
    value="{{user}}"
    *ngFor='let user of (http.getUsers() | async); let i = index'
    [ngClass]="{'active':isClicked[i]}"
    (click)="isClicked[i] = (isClicked[i]? false :true); getReceiver(user)"> 
    {{user}}
</button>

推荐阅读