我在ASP.NET Core中使用带有TypeScript的Angular 2.0.0。我的目标是在我的应用程序中基于服务器端变量创建AppConfig服务。在其他几个答案的帮助下,我能够创建以下代码:
Index.cshtml
<app>
<i class="fa fa-spin fa-5x fa-spinner"></i>
</app>
<script>
System.import('/app/main').then((m) => {
var config = {
apiUrl: @options.ApiServerUrl
};
m.RunApplication(config);
}, console.error.bind(console));
</script>
app.config.ts
import { Injectable } from "@angular/core";
@Injectable()
export class AppConfig {
apiUrl: string;
}
main.ts
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
import { AppModule } from "./app.module";
import { AppConfig } from "./app.config";
export function RunApplication(config: Object) {
var appConfig = new AppConfig();
appConfig.apiUrl = config["apiUrl"];
console.log('Created config: ', appConfig);
platformBrowserDynamic()
.bootstrapModule(AppModule, [{ providers: [{ provide: AppConfig, useValue: appConfig }] }])
.catch(err => console.error(err));
}
app.module.ts
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { HttpModule } from "@angular/http";
import { AppRouting, AppRoutingProviders } from "./app.routes";
import { AppConfig } from "./app.config";
import { AppComponent } from "./app.component";
import { DashboardComponent } from "./dashboard/dashboard.component";
import { DashboardService } from "./dashboard/dashboard.service";
@NgModule({
declarations: [
AppComponent,
DashboardComponent
],
imports: [
BrowserModule,
HttpModule,
AppRouting
],
providers: [
AppRoutingProviders,
AppConfig,
DashboardService
],
bootstrap: [AppComponent],
})
export class AppModule { }
dashboard.service.ts
import { Http } from "@angular/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs/Rx";
import "rxjs/add/operator/map";
import { AppConfig } from "../app.config";
@Injectable()
export class DashboardService {
constructor(private appConfig: AppConfig, private http: Http) {
console.log('Injected config: ', appConfig);
console.log('Injected apiUrl: ', appConfig.apiUrl);
}
}
从Chrome控制台发送
正如您所看到的,由于某些原因,创建和注入的AppConfig
不同,apiUrl
值不会出现在DashboardService
中。我怀疑错误在这里:
bootstrapModule(AppModule, [{ providers: [{ provide: AppConfig, useValue: appConfig }] }])
但我对Angular2很新,不知道如何修复它。你能指出我的问题所在吗?
答案 0 :(得分:1)
AppConfig
提供商@NgModule()
提供商传递给bootstrapModule()
使用How to pass parameters rendered from backend to angular2 bootstrap method,你应该得到你想要的东西。
答案 1 :(得分:0)
我最终将对象添加到全局变量中。
// =====文件globals.ts
import { AppConfig } from './app.config';
'use strict';
export var appConfig: AppConfig;
// =====文件app.config.ts
import { Injectable } from "@angular/core";
@Injectable()
export class AppConfig {
entityId: string;
formId: string;
}
// =====文件index.html或cshtml
<script>
System.import('app').then((m) => {
var config = {
entityId: '12',
formId: '22'
};
m.RunApplication(config);
},
console.error.bind(console)
);
</script>
// =====文件main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
import { AppConfig } from './app.config';
import myGlobals = require('./globals');
//platformBrowserDynamic().bootstrapModule(AppModule);
export function RunApplication(config: Object) {
var appConfig = new AppConfig();
appConfig.entityId = config["entityId"];
appConfig.formId = config["formId"];
console.log('Created config: ', appConfig, appConfig.entityId, appConfig.formId);
myGlobals.appConfig = appConfig;
platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch(err => console.error(err));
}
// =====文件app.module.ts
import { AppConfig } from './app.config';
import myGlobals = require('./globals');
...
@NgModule({
imports: [
...
],
declarations: [
...
],
providers: [
{
provide: AppConfig,
useValue: myGlobals.appConfig
}
],
bootstrap: [AppComponent]
})
// =====文件intro.component.ts
import { AppConfig } from "./app.config";
import myGlobals = require('./globals');
@Component({
selector: 'my-intro,[my-intro]',
templateUrl: ''
})
export class IntroComponent {
constructor() {
console.log('constructor', 'appConfig', myGlobals.appConfig);
}
}
答案 2 :(得分:0)
使用Promise保护您的路线,使用Promise加载配置设置也应该有效。
将appSettings.service与返回promise
的函数一起使用id
CanActivate后卫如下:
getAppSettings(): Promise<any> {
var observable = this.http.get(this.ApiUrl, { headers: this.headers })
.map((response: Response) => {
var res = response.json();
return res;
});
observable.subscribe(config => {
this.config= config;
console.log(this.config)
});
return observable.toPromise();
}
这将确保在构造相应组件时您的设置可用。 (使用APP_INITIALIZER并没有限制被调用的构造函数,所以我不得不使用这个技术,另外请确保,你不要导出导出中的所有组件:模块中的[])
为了保护路由并确保在调用构造函数之前加载设置,请使用路径定义路径中常用的canActivate选项
import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { AppSettingsService } from './appsettings.service';
@Injectable()
export class CanActivateViaAuthGuard implements CanActivate {
//router: Router
constructor(private appSettingsService: AppSettingsService)
{
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.appSettingsService.getAppSettings().then(() => {
return true });
}
}
appsettings的初始化应该在调用AbcComponent的构造函数之前发生,这是在Angular 2.0.1中测试并运行的