无法访问set之外的firebaseObjectObservable

时间:2017-02-09 03:51:58

标签: typescript firebase firebase-realtime-database angularfire2

首先,这是一个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);
}

1 个答案:

答案 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实时数据库的主要内容之一。