javascript - Angular - 如何在加载组件之前等待提供者获取请求完成?
问题描述
我的程序使用了我的 player.ts 文件中使用的全局变量。我将此播放器文件导入侧边栏组件,现在应用程序错误。问题是应用程序在 player.ts 中完成获取请求之前正在加载侧边栏组件。我首先在我的 app.module 中初始化 player.ts 文件。如果没有,我可以提示应用程序在加载组件之前等待吗?我尝试使用 await javascript 关键字,但所有组件和导入的文件似乎都是从 app.moudle 异步加载的。
应用程序模块.ts
import { Player } from './player';
import { SidebarComponent } from './sidebar/sidebar.component';
@NgModule({
declarations: [
AppComponent,
SidebarComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
],
providers: [Player],
bootstrap: [AppComponent]
})
export class AppModule {
constructor(private player: Player) {
console.log("first console.log yeee");
this.processPlayer()
}
async processPlayer(){
let tester1 = await this.player.loadPlayer();
}
}
sidebar.component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Player } from '../player';
@Component({
selector: 'app-sidebar',
templateUrl: './sidebar.component.html',
styleUrls: ['./sidebar.component.css']
})
export class SidebarComponent implements OnInit {
projects
focussections
constructor(private router: Router, private player: Player) { }
ngOnInit() {
//get all the project to list on sidebar
this.projects = this.player.getAllProjects();
this.focussections = this.player.getAllSections4Project(this.focusID);
}
navigate2CreateTaskQuicky(){
let info = {typeID:0}
this.router.navigate(['/createtask', JSON.stringify(info)]);
}
}
播放器.ts
@Injectable()
export class Player {
player : any
constructor(private http: HttpClient) {
this.ngOnInit();
}
async ngOnInit() {}
loadPlayer(){
return this.http.get(url)
.toPromise()
.then(
res => { // Success
this.player = res;
console.log("the player is fully loaded");
console.log(this.player);
}
);
}
getAllProjects(){
return this.player.projects;
}
getAllSections4Project(focusID){
let inboxSectionStack = [];
if(this.player){
for(let x = 0; x< this.player.sections.length; x++){
if(this.player.sections[x].project == focusID ){
inboxSectionStack.push(this.player.sections[x]);
}
}// loop through all tasks in player
}
return inboxSectionStack;
}
解决方案
您必须使用APP_INITIALIZER
提供程序。这是在AppComponent
(和任何其他组件)呈现之前运行的服务:
应用模块:
providers: [
Player,
{
provide: APP_INITIALIZER,
useFactory: initApp,
multi: true,
deps: [ Player ]
}
]
然后你就可以制作工厂了。确保工厂返回一个函数,该函数又返回一个Promise
:
export function initApp(player: Player) {
return () => this.player.loadPlayer()
}
如果您不关心 AppComponent 是否被渲染,但您不希望路由被解析,您可以将initialNavigation
路由器配置中的标志设置为 false,并使用 AppComponent 内部的服务来解析并路由到正确的路径
推荐阅读
- python - 按特定标点符号拆分
- excel - 在 Excel 中满足某些条件时增加列值
- python - 与 Python 代码相比,我如何提高 Rust 代码的性能?
- android - 是否有在 Exoplayer2 上实施“低速”擦洗的解决方案?
- python - 遍历 Python 字典以获取特定值
- javascript - 编写一个应该匹配格式“02142-1209”的正则表达式
- .net - 默认情况下阻止 .NET Core 3.0 构建 EXE 文件
- youtube - WKWEbView 在 iOS 中隐藏原生播放器的控件
- javascript - 如何获得相同编写的 html?
- node.js - 您可以使用 RESTApi 从服务器下载文件吗