ngOnInit()中的数据集在ngAfterViewInit()

时间:2017-09-04 06:04:59

标签: angular typescript firebase

我正在尝试从Firebase获取数据并将其设置为Class中的变量。我面临的问题是ngAfterViewInit()中的变量未定义。

我知道它是在ngOnInit()中设置的。我已经在Angular文档页面中阅读了Angular生命周期方法和英雄之旅示例,看看我是否正确获取数据,但它仍然无法解释这种奇怪的行为(至少对我而言!)。

ngOnInit() {
    this.http.get('https://xxxxxxxx-xxxxx.firebaseio.com/data.json').map(response => response.json())
    .subscribe(
    data => {
      for (var i = 0; i < data.length; i++) {
        var a: string = data[i]['date'];
        data[i]['date'] = new Date(a);
      }
      this.timeline = data; // declared in class
      this.timelineElements = data; // declared in class
      console.log(data); // data is not empty
      console.log(TIMELINE); // data is not empty
    },
    error => {
      console.log(error);
    }
  )}


ngAfterViewInit() {
    console.log(this.timeline); // Undefined if fetched from firebase. Works perfectly if the data is fetched locally
}

如果我尝试在本地设置两个变量,那么一切都很好。问题是当我尝试从firebase获取它时。 我是Angular世界的新手,但我的理解是,在我的情况下,ngAfterViewInit()在来自Firebase的数据到达之前被调用了吗?但不确定。

有没有办法解决这个问题?

4 个答案:

答案 0 :(得分:5)

http.get是一个异步函数,这意味着它需要一些时间才能完成。在这种情况下,在http.get完成之前调用ngAfterViewInit。

为什么要用ngOnInit和ngAfterViewInit分离所有内容呢?

答案 1 :(得分:0)

为什么你如此关心你的逻辑应该在ngAfterViewInit完成? Http调用是异步的,接收数据时应该发生什么,应该在ngAfterViewInit进行。

视图已初始化&gt; ngAfterViewInit已解雇&gt;您可以在此之后加载数据,并且您应该处理订阅onSuccess函数中的数据。

所以:

.subscribe(
    data => {
    //this is where you should do whatever you need with the data
    //you should not care about ngAfterViewInit at all with respect to getting data
})

如果你做了一些假设,你将在任何生命周期钩子中都有数据,那么你只是做了一些不好的假设,你需要重新设计你的组件逻辑。 有关这方面的帮助,您可能应该使用组件代码提出新问题。

答案 2 :(得分:0)

在这里你试着点击ngOnInit里面的api,这很好,但你不知道服务器返回响应需要多少时间,同时Angular 2有自己的生命周期独立于你的后端。现在来点Http。以下是使用Angular制作和处理对Web服务的HTTP请求所需的所有类型和内容:

  • Http 是一个Angular 2服务,它提供用于制作HTTP的API 请求与HTTP动词相对应的方法,如get,post, 放等等
  • 响应是一种表示来自HTTP服务的响应的类型 并遵循fetch API规范
  • Observable 是Angular 2中使用的异步模式 observable来自观察者设计模式作为对象 当一些有趣的东西通知感兴趣的观察者一方 发生。在RxJS中,它被推广到管理数据序列 或事件(也称为流),可与其他人组合 可观察并提供许多称为的实用功能 让你获得惊人成就的运营商。

  • rxjs / add / operator / map 是指rxjs map运算符。 rxjs是一个非常大的 具有大量运算符和功能的库。最佳做法是 只导入你需要使用的rxjs的部分,这就是我们的原因 首先只导入地图运算符(最常见的一个) 使用过的运营商)。

因此,其中一个解决方案是,除了在 ngAfterViewInit 中获取数据之外,您还可以在响应中调用自己的函数:

像这样:

ngOnInit() {
    this.http.get('https://xxxxxxxx-xxxxx.firebaseio.com/data.json').map(response => response.json())
    .subscribe(
    data => {
      for (var i = 0; i < data.length; i++) {
        var a: string = data[i]['date'];
        data[i]['date'] = new Date(a);
      }
      this.timeline = data; // declared in class
      this.timelineElements = data; // declared in class
      console.log(data); // data is not empty
      console.log(TIMELINE); // data is not empty
      getTheData(data);
    },
    error => {
      console.log(error);
    }
  )};

 this.getTheData(data){
     this.finalData = data;
 }

答案 3 :(得分:0)

嘿,有同样的问题,我的值在NgAfterViewInit中不可用。

因此,我从OnInit中获取代码,并将其放置在Constructor()中

print(precision_score)

所以在此之后,我的值在NgAfterViewInit中可用。