Angular 获取和存储全局变量
我正在努力解决一个简单的概念,我可以用C#轻松地完成,但不能用Angular 我试图将用户配置文件存储在我在每个组件中添加的服务中,因此我不会在每次加载/显示组件时都获取配置文件 因此,我创建了一个服务,其中构造函数获取用户配置文件,并将其保存在一个变量中,并对我的所有组件使用getter 我遇到的问题是,当组件调用getter时,变量是net set,因为服务还没有响应。这会导致未定义的错误并破坏组件,因为配置文件在组件代码中至关重要 在C#中,我只需在获取概要文件时放入1 wait,这样其他所有内容都可以不等待地运行,因为我知道数据就在那里 但在我看来,我试过了,但似乎不起作用Angular 获取和存储全局变量,angular,Angular,我正在努力解决一个简单的概念,我可以用C#轻松地完成,但不能用Angular 我试图将用户配置文件存储在我在每个组件中添加的服务中,因此我不会在每次加载/显示组件时都获取配置文件 因此,我创建了一个服务,其中构造函数获取用户配置文件,并将其保存在一个变量中,并对我的所有组件使用getter 我遇到的问题是,当组件调用getter时,变量是net set,因为服务还没有响应。这会导致未定义的错误并破坏组件,因为配置文件在组件代码中至关重要 在C#中,我只需在获取概要文件时放入1 wait,这样其他
export class SharedService {
private userProfile;
constructor(private http: HttpService) {
this.initProfile();
}
async initProfile(): Promise < void > {
this.userProfile =await this.http.getProfile().subscribe((data: any) => {
//...
}
});
getUserProfile() {
return this.userProfile;
}
}
在组件中,当我调用getUserProfile函数时,服务会立即使用空的userProfile进行应答
编辑:
我使用非常讨厌的代码片段成功地实现了所需的行为,但这应该清楚地表明我正在尝试实现什么。在my profile.component.ts中:
async ngOnInit(): Promise<void> {
while (this.profile == null) {
await this.sharedService.sleep(500);
this.profile = this.sharedService.getUserProfile();
}
if (this.profile.isadmin){
this.CalculateStuff();
}
//
//imagine here even more code using the this.profile variable in if statements,
//cases, etc.
//
}
事实上,我必须编写一个睡眠函数来实现这一点,这对我来说是一个明确的信号,表明我做错了什么。这就是我来这里的原因。你就快到了。您正在等待的订阅不适用于
async
/wait
。只需执行以下操作。把它转换成承诺,这样你就可以等待它了
async ngOnInit(): Promise<void> {
this.profile = await this.sharedService.getUserProfile().toPromise();
if (this.profile.isadmin){
this.CalculateStuff();
}
}
同样如前所述,RxJs的基本知识将非常有用,可以解决许多早期问题 另一种方法是使服务中的
userProfile
成为可观察的多播(如带有缓冲区1的RxJSReplaySubject
)。这样就不需要将可观察到的东西与承诺混为一谈
服务
从'rxjs'导入{ReplaySubject};
导出类共享服务{
private userProfile=新的ReplaySubject(1);
构造函数(私有http:HttpService){
this.initProfile();
}
initProfile(){
这是.http.getProfile().subscribe({
下一步:(数据:任意)=>{
this.userProfile.next(data);//{}//如果您喜欢使用承诺,请将observable转换为promise:this.userProfile=wait this.http.getProfile().toPromise()
;应该更好你不能等待订阅或观测并获得结果值,这只适用于承诺。你可以按照@Andrei的建议使用.toPromise
,或者倾向于RxJS(因为角度的大部分是基于观测值的,我建议后者)。谢谢你的回复。我正在努力避免将我所有的代码都放在订阅答案中。如前所述,很多代码取决于配置文件的内容,因此,在发布之前,这就是我所做的。只要服务中没有设置userprofile,难道不可能简单地停止代码执行流吗?因为ng else取决于它。还是我遗漏了什么?如果您需要代码中的值来做出决策,您如何处理承诺?是的,这在我回答中的第一段代码中是可能的(订阅也是可能的,但有点复杂)。当您将可观察内容转换为承诺并等待它时。您的函数将等待承诺完成(成功或抛出错误)。承诺将完成,然后您可以像“正常”一样使用this.userProfile
变量。很抱歉,是的,您是对的,代码块正在停止。我的问题表述得很糟糕。我的意思是,我的组件似乎没有等待代码执行完毕。它将从共享服务获取未定义/未设置的用户配置文件,即使共享服务仍在“等待”在http服务的getprofile上。啊,是的。这是Angular中异步代码的一个基本部分。您需要使用ngIf=“userProfile”
在模板中进行空检查(这是不需要的)为了避免尝试使用空值执行任何操作。当配置文件承诺完成时,该值将不再为空,模板将对新的“非空”配置文件执行更新。您能否提供一个代码示例,说明到底是什么导致了问题?好的。再次感谢您抽出时间!我肯定需要提出一些建议(很多?)在rxjs中,这听起来像是一门外语:(但谢谢你把这篇文章写出来。等我对rxjs有了更好的了解后,我会再讨论它。希望很快!@Hedi:虽然这篇文章可以提供有价值的参考,但我不推荐它作为一个起点。它们是用来补充现有知识的直截了当的信息。相反,你可以开始使用。它们为每一个乐趣提供了更多的上下文。)操作和运算符,并提供易于掌握的示例。您还可以使用来补充LearnRxJS。再次感谢您提供的信息。我将为您的评论添加书签,并在启动RXJS时返回!
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async ngOnInit(): Promise<void> {
this.profile = await this.sharedService.getUserProfile().toPromise();
if (this.profile.isadmin){
this.CalculateStuff();
}
}
this.http.getProfile().subscribe((userProfile: any) => {
// do userProfile actions here
});
//Since subscribe is an async callback, anything outside that block will have userProfile undefined.