我有一个网络应用程序向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中,但是如果我尝试将其记录到控制台,它会显示 - 证明该方法有效,但由于某种原因它没有显示。
答案 0 :(得分:0)
这是因为您正在执行异步任务,并且您正在等待它完成以便更改值。
如果它位于组件中,您会看到由于更改检测策略而更改的值,但在这种情况下,它位于管道>内strong>和管道的工作方式不同。
Angular通过在每个DOM事件之后运行的更改检测进程查找数据绑定值的更改:每次击键,鼠标移动,计时器滴答和服务器响应。这可能很昂贵。 Angular努力尽可能地降低成本。 当您使用管道时,Angular会选择更简单,更快速的更改检测算法。
因此,值会更改,但视图未更新,因为未执行更改检测。
要在管道内发生事件的情况下执行完整更改检测周期,您可以将当前管道转换为impure pipe,只需在元数据中添加字段:
@Pipe({
name: 'usernamePipe',
pure: false
})
答案 1 :(得分:0)
简化下面代码的管道,摆脱订阅和额外似乎可以解决问题。调用DOM中的管道后,还要包含异步 ,否则不显示任何内容。
return this.auth.getUserInfo(uid);
希望有人觉得这很有用,如果它不适合你,请随时给我留言。