向 firebase 实时数据库发出请求并使用 angular 管道过滤结果

Making request to firebase realtime database and filtering result with angular pipe

我有一个网络应用程序可以向 firebase 实时数据库请求用户信息。

服务调用以下方法时返回信息:

//searches db for user information
getUserInfo(uid){
    return this.db.list('users/', ref => ref.orderByKey().equalTo(uid)).valueChanges();
}

此方法在如下定义的管道内触发:

@Pipe({
 name: 'usernamePipe'
})

export class UsernameFilter implements PipeTransform{

constructor(private auth: AuthenticationService){
}

transform(uid: any):any {

//return item if neither filter nor list exists
if(!uid){
  return uid;
}

var user = {};

this.auth.getUserInfo(uid)
  .subscribe(res => {
    user = res;
    return user[0].userInfo.firstName;
  })
 }
}

管道用于通过调用我的组件内的实时数据库获得的消息列表,如下所示:

<div class="message-summary" *ngFor="let msg of messageThread.messages | keys; let last = last" (click)="getThreadDetails(messageThread.messages)">
    <span class="time">{{msg.timeSent | date: 'short'}}</span>
    <span class="sender-name" *ngIf="msg.from !== 'admin'">{{msg.from | usernamePipe | async}}</span>
</div>

keys 管道是另一个自定义管道,我用来将从初始请求返回到实时数据库的对象转换为数组,以便用 *ngFor

进行迭代

问题是转换后的数据未显示在 DOM 中,但如果我尝试将其记录到控制台,它会显示 - 证明该方法有效但由于某种原因未显示。

发生这种情况是因为您正在执行异步任务并且您正在等待它完成以更改值。

如果它在 Component 内部,您会看到值因 change detection 策略而改变,但在这种情况下它是Pipe 和管道的工作方式不同。

来自 Angular documentation :

Angular looks for changes to data-bound values through a change detection process that runs after every DOM event: every keystroke, mouse move, timer tick, and server response. This could be expensive. Angular strives to lower the cost whenever possible and appropriate. Angular picks a simpler, faster change detection algorithm when you use a pipe.

所以值发生了变化,但视图没有更新,因为没有执行变化检测

要在 Pipe 内部发生事件的情况下也执行完整的更改检测周期,您可以将当前管道转换为 impure pipe,只需在中添加一个字段元数据:

@Pipe({
 name: 'usernamePipe',
 pure: false
})

简化下面代码的管道,去掉订阅和附加功能似乎可以解决问题。在 DOM 中调用管道后,异步 必须包含 否则什么也不会显示。

return this.auth.getUserInfo(uid);

希望有人觉得这有用,如果它不适合你,请随时给我发消息。