我正在尝试从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的数据到达之前被调用了吗?但不确定。
有没有办法解决这个问题?
答案 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请求所需的所有类型和内容:
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中可用。