首先,这是一个Angular2应用程序。我刚刚开始使用Angular2和Firebase构建。我也在使用AngularFire2。我知道我的服务正在运行,因为我可以在订阅后立即打印blog.title
。但这是我可以访问结果的唯一地方。它在其他地方给我一个undefined
错误。无论我在模板中使用{{}}还是在类中,我都会得到相同的结果。我不确定我做错了什么。我也是观察者的新手。
export class BlogEditComponent implements OnInit {
blogForm: FormGroup;
blog$: FirebaseObjectObservable<Blog>;
blog: Blog;
constructor(private route: ActivatedRoute,
private router: Router,
private fb: FormBuilder,
private blogService: BlogService) { }
ngOnInit() {
this.isNew = false;
this.blog$ = this.blogService.getBlogFromId(this.route.snapshot.params['id']);
this.blog$.subscribe(snapshot =>{
this.blog = snapshot;
console.log(this.blog.title); //prints out fine
});
console.log(this.blog.title); //throws error here
}
}
BlogService
getBlogFromId(id: String): FirebaseObjectObservable<Blog> {
return this.af.database.object('blogs/' + id);
}
答案 0 :(得分:2)
这是预期的行为:回调的运行时间与周围的代码不同。
最容易看到你忽略实际值并只记录一些静态字符串:
ngOnInit() {
this.blog$ = this.blogService.getBlogFromId(this.route.snapshot.params['id']);
console.log("before subscribing");
this.blog$.subscribe(snapshot =>{
console.log("in callback");
});
console.log("after subscribing");
}
运行此操作时,日志记录将为:
订阅前订阅后
回调中的
这可能不是您自然期望的顺序。但这是记录在案的行为:由于数据是从远程服务器加载的,因此可能需要一些时间才能回复您。在加载时,subscribe
调用后的代码会继续。
我经常发现通过重构我的问题来解决这个问题最容易。通常你会说&#34;先得到博客文章,然后打印标题&#34;。但现在将其重新构建为&#34;开始获取博客文章;当你得到它,打印标题&#34;。
在代码中,这意味着您将需要标题的所有代码模式化为回调,就像您的第一个日志记录语句一样。所以:
ngOnInit() {
this.isNew = false;
this.blog$ = this.blogService.getBlogFromId(this.route.snapshot.params['id']);
this.blog$.subscribe(snapshot =>{
this.blog = snapshot;
console.log(this.blog.title);
});
}
这还有一个优点,即如果博客标题发生变化,博客标题将会打印出来,这是Firebase实时数据库的主要内容之一。