angular - 获取和存储全局变量
问题描述
我正在为一个简单的概念而苦苦挣扎,我可以在 C# 中轻松完成,但在 Angular 中却不行。
我正在尝试将用户配置文件存储在我在每个组件中添加的服务中,因此每次加载/显示组件时我都不会获取配置文件。
因此,我创建了一个服务,构造函数在其中获取用户配置文件,并将其保存在一个变量中,并对我的所有组件使用 getter。
我遇到的问题是,当组件调用 getter 时,变量已设置为 net,因为服务尚未响应。这会导致未定义的错误并破坏组件,因为配置文件在组件的代码中至关重要。
在 C# 中,我会在获取配置文件时简单地放置 1 await,以便其他一切都可以运行而无需等待,因为我知道数据就在那里。
但是在 Angular 中,我尝试过,但它似乎不起作用。
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;
}
}
获取配置文件:
getProfile() {
return this.shttp.get(environment.apiEndpoint + 'Getprofile/', {
headers: new HttpHeaders({
'Content-Type': 'application/json',
Accept: '*/*'
})
});
}
在组件中,当我调用 getUserProfile 函数时,服务会立即使用空的 userProfile 进行响应。
编辑:我设法通过非常讨厌的代码片段获得所需的行为,但这应该清楚我想要完成的事情。在我的 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.
//
}
睡眠功能
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
我必须编写一个睡眠函数来实现这一点,这对我来说是一个明确的信号,表明我做错了。这就是我在这里的原因。
解决方案
另一种方法是使服务中的多播可观察(如带有缓冲区 1userProfile
的 RxJS )。ReplaySubject
这样就不需要将 observables 与 Promise 混合在一起。
服务
import { ReplaySubject } from 'rxjs';
export class SharedService {
private userProfile = new ReplaySubject<any>(1);
constructor(private http: HttpService) {
this.initProfile();
}
initProfile() {
this.http.getProfile().subscribe({
next: (data: any) => {
this.userProfile.next(data); // <-- push the new profile
},
error: (error: any) => { } // <-- handle error
});
getUserProfile(): Observable<any> { // <-- return observable here
return this.userProfile.asObservable();
}
}
现在在组件中,您可以从服务订阅主题。此外,当组件关闭/销毁时,您可以使用takeUntil
operator with来关闭打开的订阅。Subject
零件
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
export class SomeComponent implements OnInit, OnDestroy {
public userProfile: any;
private closed$ = new Subject<any>();
constructor(private shared: SharedService) { }
ngOnInit() {
this.shared.getUserProfile().pipe(
takeUntil(this.closed$)
).subscribe({
next: (data: any) => {
this.userProfile = data;
// other statements that depend on `this.userProfile`
}
});
}
ngOnDestroy() {
this.closed$.next(); // <-- close open subscription(s)
}
}
推荐阅读
- javascript - 数组差异,嵌套的 For 循环
- javascript - TypeError:无法读取未定义 NextJS 的属性“地图”
- apache-kafka-connect - Debezium MongoDB 连接器不执行初始快照
- javascript - 我需要帮助来使用 javascript 隐藏未选择的日子
- shell - 删除命令提示符输出中的换行符
- javascript - Javascript 与 Python 中的递归深度优先搜索
- python - Python 编译器跳过“if”语句
- python - 使用弹出登录窗口进行网页抓取
- javascript - 在拖放和拖动中反应 DnD 孩子
- python - 将 3d 列表转换为 numpy 数组会插入不需要的元组