当angular 2 app被引导时,我们想调用一个rest api,我的意思是应该对应用程序做的第一件事就是调用这个api并获取应用程序所需的一些数据。
反正有没有实现这个目标?我看到了以下文章,但它是用于Angular 2的beta版本
答案 0 :(得分:92)
您可以使用APP_INITIALIZER在bootstrap上调用服务方法。您需要在provider
中为其定义AppModule
。
以下是如何执行此操作的示例。
StartupService ( startup.service.ts )
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
@Injectable()
export class StartupService {
private _startupData: any;
constructor(private http: Http) { }
// This is the method you want to call at bootstrap
// Important: It should return a Promise
load(): Promise<any> {
this._startupData = null;
return this.http
.get('REST_API_URL')
.map((res: Response) => res.json())
.toPromise()
.then((data: any) => this._startupData = data)
.catch((err: any) => Promise.resolve());
}
get startupData(): any {
return this._startupData;
}
}
AppModule ( app.module.ts )
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { StartupService } from './startup.service';
// ...
// Other imports that you may require
// ...
export function startupServiceFactory(startupService: StartupService): Function {
return () => startupService.load();
}
@NgModule({
declarations: [
AppComponent,
// ...
// Other components & directives
],
imports: [
BrowserModule,
// ..
// Other modules
],
providers: [
StartupService,
{
// Provider for APP_INITIALIZER
provide: APP_INITIALIZER,
useFactory: startupServiceFactory,
deps: [StartupService],
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
AppComponent ( app.component.ts )
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { StartupService } from './startup.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
constructor(private router: Router, private startup: StartupService ) { }
ngOnInit() {
// If there is no startup data received (maybe an error!)
// navigate to error route
if (!this.startup.startupData) {
this.router.navigate(['error'], { replaceUrl: true });
}
}
}
答案 1 :(得分:11)
我使用Santanu提供的答案遇到的一件事是,除非在StartupService
之前的提供程序中定义APP_INITIALIZER
,否则它无法工作。使用Angular 4.x
,因此在我的情况下,提供者部分看起来像这样:
providers: [
UserService,
{
provide: APP_INITIALIZER,
useFactory: userServiceFactory,
deps: [UserService],
multi: true
}
答案 2 :(得分:0)
这是一个article,它更详细地解释了APP_INITIALIZER,它还显示了角度如何使用它。
答案 3 :(得分:0)
@efirvida和@Santanu Biswas
我尝试了您的答案,但它起作用了(APP_INITIALIZER中的内容发生了 在app.component引导之前)。
不幸的是,所有组件的注入都在此之前进行,因此 这些组件引用的变量尚未准备就绪。
我提出了一个问题here。
与@magos提出的问题基本相同。
任何帮助都被接受的^^
我能想到的唯一解决方案是在app.component中进行API调用以获取配置数据,但是这对OP和我来说都不合适。 如果我不能解决同步问题,将是我的解决办法