希望您一切都好,当我想开发Angular应用程序时遇到了一个小问题,我想要的是带回后端部分的元素“菜单”列表以在应用程序中使用它。 / p>
问题是当我使用get方法带回数据时,该数据被带回到执行结束,当我想在控制台中记录从backEnd带入的对象时,我注意到了这一细节。
正如您所看到的,当我在构造函数中或在Onint()方法中记录MenuItem对象时,我得到一个空对象,但是当我在服务类中记录该对象时,我得到了menuTtem对象,因此我知道首先执行OnInit和Construtor,然后执行http get方法。
我的问题是这样的: 有没有一种方法可以恢复数据而不陷入这个问题?
这是我在menu.component中的构造函数:
constructor(public appSettings: AppSettings, public menuService: MenuService) {
this.settings = this.appSettings.settings;
this.menuItems = this.menuService.getVerticalMenuItems();
console.warn('this.menuItems in the construtor', this.menuItems)
}
和我的Menu.service服务的getMenuItems()方法
public getMenuItems(): Menu[] {
this.http.get<Menu[]>(this.url + 'all').subscribe(
data => { this.menudata = data
console.warn('this.menudata in Service', this.menudata)
}
)
return this.menudata ;
}
如有任何建议,请不要犹豫。
谢谢!
答案 0 :(得分:1)
好吧,对我来说,代码似乎可以正常工作。您只需要了解JS的异步性质。您不能使用固有的慢速网络通信来阻止JS主线程(HTTP请求-响应往返可能需要200毫秒)。
在这种情况下,get
函数返回一个Observable
,您可以在其中subscribe
进行新事件。就是这样。在这种情况下,事件是HTTP响应。 HTTP响应到达时,它将data
分配给this.menudata
并记录服务消息。
因此,您立即subscribe
到Observable
,但是订阅本身会在HTTP响应到达时得到处理。它不能等待响应然后继续。这会破坏应用程序的响应能力。
//有关该概念的更多信息,请使用官方Angular guide的相关部分。
答案 1 :(得分:0)
在ngOnInit()
中而不是在构造函数中调用您的方法。调用getVerticalMenuItems()
方法时,线程不等待响应,因此参数返回undefined
。这就是为什么在那里变得不确定的原因。
进行如下更改,
ngOnInit() {
this.settings = this.appSettings.settings;
this.menuService.getVerticalMenuItems();
console.warn('this.menuItems in the construtor', this.menuItems)
}
public getMenuItems() {
this.http.get<Menu[]>(this.url + 'all').subscribe(
(data: any) => {
this.menuItems = data
console.warn('this.menuItems in Service', this.menuItems )
}
)
}
在Component中订阅您的Observable响应是一种更好的做法。
答案 2 :(得分:0)
您必须在组件内部订阅Observable,以便可以从后端访问来自后端的数据。
请注意,当您调用Menu.service的getMenuItems()方法时,它会返回在特定时间分配给menudata属性的数据,在第一次调用该方法的情况下为null。
之所以发生这种情况,是因为可观察到的对象随着时间的推移“存在延迟”,换句话说,这是异步操作
public getMenuItems(): Observable<Menu[]> {
return this.http.get<Menu[]>(this.url + 'all');
}
以及您内部的组件
ngOnInit () {
this.menuService.getVerticalMenuItems().subscribe((data) => {
this.data = data;
});
}
答案 3 :(得分:0)
尝试:在您的ngOnInit()中订阅您的API调用,而不是您的服务组件
ngOnInit() {
this.settings = this.appSettings.settings;
this.menuService.getMenuItems().subscribe(
(data: any) => {
console.warn('this.menuItems in Service', data )
}
);
}
在您的服务组件中,执行此操作。不要忘记返回服务电话
public getMenuItems() {
return this.http.get<Menu[]>(this.url + 'all')
}