Angular 4.x中无法在ngOnInit()外部访问JSON响应数据
为什么Angular中HTTP请求的数据无法在ngOnInit外部访问?
这个问题其实是JavaScript异步编程的经典坑,我来给你拆解清楚:
核心原因有两个:
1. 变量作用域限制
你在subscribe回调函数里的data是局部变量,它只在这个回调函数内部有效,组件其他位置的代码根本看不到这个变量。所以你直接写在ngOnInit外面的console.log('menu data outside init', data);本身就会报错——因为data在这里是未定义的。
2. 异步执行顺序问题
Angular的HttpClient.get()发起的是异步HTTP请求:浏览器会先把请求发出去,然后立刻继续执行后面的同步代码,等服务器返回数据后,才会触发subscribe里的回调函数。
你写在ngOnInit外面的console.log是同步代码,会在组件初始化阶段就执行,这时候HTTP请求还在网络传输中,服务器还没返回数据,回调函数根本没触发,就算你把data改成组件级别的属性,这时候它也是undefined。
解决方案:用组件属性存储异步数据
要在外部访问请求到的数据,你需要把数据存到组件的实例属性里,然后在数据加载完成后再使用它:
export class SidebarComponent implements OnInit { // 定义组件属性,用来存储请求到的数据 menuData: any; constructor(private http: HttpClient, private userService: UserService) { } ngOnInit() { this.http.get('https://dev.myapp.com/api/angularfour/auth', { params: new HttpParams() .set('token', this.userService.getAuth().__token) .set('apiversion', '1') .set('appid', this.userService.getAuth().appid) }) .subscribe(data => { console.log('data', data); // 把异步获取的数据赋值给组件属性 this.menuData = data; // 这里可以直接访问到数据 console.log('menu data inside subscribe', this.menuData); }); } // 在其他方法里访问数据时,要确保数据已经加载完成 checkMenuData() { if (this.menuData) { console.log('menu data in method', this.menuData); } else { console.log('数据还没加载完成哦'); } } }
如果是在模板里使用数据,建议结合*ngIf避免未定义的问题:
<div *ngIf="menuData"> <!-- 这里可以安全地使用menuData --> {{ menuData.someProperty }} </div>
内容的提问来源于stack exchange,提问作者Zabs
相关产品推荐
相关产品推荐

