Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 无法访问集合外部的firebaseObjectObservable_Typescript_Firebase_Firebase Realtime Database_Angularfire2 - Fatal编程技术网

Typescript 无法访问集合外部的firebaseObjectObservable

Typescript 无法访问集合外部的firebaseObjectObservable,typescript,firebase,firebase-realtime-database,angularfire2,Typescript,Firebase,Firebase Realtime Database,Angularfire2,首先,这是一个Angular2应用程序。我刚开始建造Angular2和Firebase。我也在使用AngularFire2。我知道我的服务正在发挥作用,因为我可以在订阅后立即打印出blog.title。但那是我唯一能得到结果的地方。在其他地方,它给了我一个未定义的错误。无论是在带有{{}的模板中还是在类中使用它,我都会得到相同的结果。我不确定我做错了什么。我对可观察事物也是陌生的 export class BlogEditComponent implements OnInit { blogF

首先,这是一个Angular2应用程序。我刚开始建造Angular2和Firebase。我也在使用AngularFire2。我知道我的服务正在发挥作用,因为我可以在订阅后立即打印出
blog.title
。但那是我唯一能得到结果的地方。在其他地方,它给了我一个
未定义的
错误。无论是在带有{{}的模板中还是在类中使用它,我都会得到相同的结果。我不确定我做错了什么。我对可观察事物也是陌生的

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
  }

}
导出类BlogEditComponent实现OnInit{
blogForm:FormGroup;
blog$:FirebaseObjectObservable;
博客:博客;
构造函数(专用路由:ActivatedRoute,
专用路由器:路由器,
私人fb:FormBuilder,
私有blogService:blogService{}
恩戈尼尼特(){
this.isNew=false;
this.blog$=this.blogService.getBlogFromId(this.route.snapshot.params['id']);
此.blog$.subscribe(快照=>{
this.blog=快照;
console.log(this.blog.title);//很好地打印出来
});
console.log(this.blog.title);//在此处抛出错误
}
}
博客服务

getBlogFromId(id: String): FirebaseObjectObservable<Blog> {
  return this.af.database.object('blogs/' + id);
}
getBlogFromId(id:String):FirebaseObjectObservable{
返回此.af.database.object('blogs/'+id);
}

这是预期的行为:回调在与其周围的代码不同的时间运行

最容易看到的是,忽略实际值,只记录一些静态字符串:

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
调用后的代码继续

我经常发现,通过重新思考我的问题,在这个范围内工作是最容易的。通常你会说“先得到博文,然后打印标题”。但现在,将其重新定义为“开始获取博客文章;当您获得它时,打印标题”

在代码中,这意味着您将需要标题的所有代码模式化到回调中,就像您的第一条日志语句一样。因此:

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实时数据库的主要功能之一。

谢谢。我早该知道的。我一直用Android在后台线程处理网络电话,但由于某些原因,这对我来说并不合适。