首页 > 解决方案 > 无法从 Angular 11 中的 httpCilent 模块将数据分配给类变量(例如,在 http.get().subscribe(...) 内部)

问题描述

这是我的第一个 Stack Overflow 帖子,如果我的格式不正确,我会如此赤裸裸的。

这是我的第一个 Angular 项目,我无法将从 http.get().subscribe(...) 方法检索到的数据分配给我的组件类变量。

我的组件:

...
export class LeafletMapComponent implements OnInit, AfterViewInit {

  data

  constructor(private ps: PeopleService, private NgZone: NgZone) {}


  ngAfterViewInit(): void { 

       console.log(this.allData) **DOESN'T WORK (logs undefined)**

  }


  ngOnInit(): void {

    this.ps.httpGetData().subscribe( data => {

      this.data= data
      console.log(this.data) ***WORKS (logs all my data) BUT...***
    })
    
    console.log(this.data) ***THIS DOESN'T WORK... WHY? (logs undefined)***
    
  }
}

我的服务:

...

@Injectable({
  providedIn: 'root'
})
export class PeopleService implements OnInit {
  
  ...

  httpGetData() {
    return this.http.get<any>(this.URL) **WORKS**
  }

  ...
}

我的问题是:在这段代码中

ngOnInit(): void {

    this.ps.httpGetData().subscribe( data => {

      this.data= data
      console.log(this.data) ***WORKS (logs all my data) BUT...***
    })
    
    console.log(this.data) ***THIS DOESN'T WORK... WHY? (logs undefined)***    
}


因为我已经将我的数据分配给了类变量(this.data = data)

.subscribe( data => {this.data = data})

方法,我假设我可以在 ngOnInit() 函数中的 subscribe 方法之后立即执行 console.log(this.data),我假设 this.data 已经被初始化并且可以在任何地方访问

我想在组件加载后立即检索数据,将其分配给我的类变量,以便我的变量可以在 ngAfterViewInit() 函数中使用。但是,在 .subscribe() 方法中,我可以将返回的数据分配给我的类变量“this.data”并记录它,但是,console.log(this.data)只能在 .subscribe() 方法中使用,别无他处。

此外,NgAfterViewInit() 是在 ngOnInit() 之前还是之后运行?我正在尝试从 NgAfterInit() 函数访问我的类变量(this.data),但我必须先从我的服务中获取数据才能做到这一点......

这是否与修改 Observable 对象有关?

编辑:当我更改为异步函数时,console.log(this.data) 现在可以在 ngOnInit 函数中工作

async ngOnInit(): Promise<void>{
    const res = await this.ps.httpGetData().toPromise()
    this.data = res
}

但是 ngAfterViewInit 不会检测到更改,因为它仍在为值 this.data 记录 undefined。

请提前帮助和感谢!

标签: angularrxjsobservable

解决方案


您的代码正确分配了数据,但是,您似乎不清楚异步代码的概念。

当您调用subscribeobservable 时,这是一个异步调用,这意味着您的代码会继续执行,而无需等待 observable 的执行完成。换句话说,代码发送请求并继续执行而不等待响应。一旦响应可用,subscribe就会执行作为参数提供给方法的回调函数。这就是为什么console.log()您在subscribe不记录任何内容后调用的原因。

至于你的问题ngAfterViewInit,它在之后执行ngOnInit

在Angular 文档中阅读更多相关信息


推荐阅读