Bod*_*zio 71 javascript angular
有没有办法将后端呈现的参数传递给angular2 bootstrap方法?我想为使用BaseRequestOptions的所有请求设置http标头,并使用后端提供的值.我的main.ts文件看起来像这样:
import { bootstrap } from '@angular/platform-browser-dynamic';
import { AppComponent } from "./app.component.ts";
bootstrap(AppComponent);
Run Code Online (Sandbox Code Playgroud)
我发现如何将这个参数传递给root组件(/sf/answers/2488755531/),但是当我开火bootstrap方法时我需要它......有什么想法吗?
编辑:
webpack.config.js内容:
module.exports = {
entry: {
app: "./Scripts/app/main.ts"
},
output: {
filename: "./Scripts/build/[name].js"
},
resolve: {
extensions: ["", ".ts", ".js"]
},
module: {
loaders: [
{
test: /\.ts$/,
loader: 'ts-loader'
}
]
}
};
Run Code Online (Sandbox Code Playgroud)
Gün*_*uer 93
UPDATE2
更新 AoT
要与AoT合作,需要将工厂关闭搬出
function loadContext(context: ContextService) {
return () => context.load();
}
@NgModule({
...
providers: [ ..., ContextService, { provide: APP_INITIALIZER, useFactory: loadContext, deps: [ContextService], multi: true } ],
Run Code Online (Sandbox Code Playgroud)
另见https://github.com/angular/angular/issues/11262
更新 RC.6和2.0.0最后的例子
function configServiceFactory (config: ConfigService) {
return () => config.load();
}
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule,
routes,
FormsModule,
HttpModule],
providers: [AuthService,
Title,
appRoutingProviders,
ConfigService,
{ provide: APP_INITIALIZER,
useFactory: configServiceFactory
deps: [ConfigService],
multi: true }
],
bootstrap: [AppComponent]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)
如果不需要等待初始化完成,也可以使用`class AppModule {}的构造函数:
class AppModule {
constructor(/*inject required dependencies */) {...}
}
Run Code Online (Sandbox Code Playgroud)
提示(循环依赖)
例如,注入路由器可能会导致循环依赖.要解决此问题,请注入Injector并获取依赖关系
this.myDep = injector.get(MyDependency);
Run Code Online (Sandbox Code Playgroud)
而不是MyDependency直接注入:
@Injectable()
export class ConfigService {
private router:Router;
constructor(/*private router:Router*/ injector:Injector) {
setTimeout(() => this.router = injector.get(Router));
}
}
Run Code Online (Sandbox Code Playgroud)
更新
这应该在RC.5中相同,但是将提供程序添加到providers: [...]根模块而不是bootstrap(...)
(尚未自我测试).
更新
完全在Angular中完成这个有趣的方法在这里解释https://github.com/angular/angular/issues/9047#issuecomment-224075188
您可以使用
APP_INITIALIZER哪个将在应用程序初始化时执行函数,并在函数返回promise时延迟它提供的功能.这意味着应用程序可以在没有太多延迟的情况下进行初始化,您还可以使用现有的服务和框架功能.例如,假设您有一个多租户解决方案,其中站点信息依赖于它所服务的域名.这可以是[name] .letterpress.com或在完整主机名上匹配的自定义域.我们可以通过使用隐藏这是一个承诺的事实
APP_INITIALIZER.在引导程序中:
Run Code Online (Sandbox Code Playgroud){provide: APP_INITIALIZER, useFactory: (sites:SitesService) => () => sites.load(), deps:[SitesService, HTTP_PROVIDERS], multi: true}),sites.service.ts:
Run Code Online (Sandbox Code Playgroud)@Injectable() export class SitesService { public current:Site; constructor(private http:Http, private config:Config) { } load():Promise<Site> { var url:string; var pos = location.hostname.lastIndexOf(this.config.rootDomain); var url = (pos === -1) ? this.config.apiEndpoint + '/sites?host=' + location.hostname : this.config.apiEndpoint + '/sites/' + location.hostname.substr(0, pos); var promise = this.http.get(url).map(res => res.json()).toPromise(); promise.then(site => this.current = site); return promise; }注意:
config只是一个自定义配置类.rootDomain将是'.letterpress.com'这个例子,并允许像这样的事情aptaincodeman.letterpress.com.任何组件和其他服务现在都可以
Site注入它们并使用.current属性,该属性将是一个具体的填充对象,无需等待应用程序中的任何承诺.这种方法似乎削减了启动延迟,如果你等待加载大型Angular bundle然后在bootstrap开始之前再发送另一个http请求,那么这种启动延迟非常明显.
原版的
您可以使用Angulars依赖注入传递它:
var headers = ... // get the headers from the server
bootstrap(AppComponent, [{provide: 'headers', useValue: headers})]);
Run Code Online (Sandbox Code Playgroud)
class SomeComponentOrService {
constructor(@Inject('headers') private headers) {}
}
Run Code Online (Sandbox Code Playgroud)
或BaseRequestOptions直接提供准备
class MyRequestOptions extends BaseRequestOptions {
constructor (private headers) {
super();
}
}
var values = ... // get the headers from the server
var headers = new MyRequestOptions(values);
bootstrap(AppComponent, [{provide: BaseRequestOptions, useValue: headers})]);
Run Code Online (Sandbox Code Playgroud)
小智 30
在Angular2最终版本中,APP_INITIALIZER提供程序可用于实现您的需求.
我写了一个完整的例子:https://gist.github.com/fernandohu/122e88c3bcd210bbe41c608c36306db9
要点示例是从JSON文件读取,但可以轻松更改为从REST端点读取.
你需要的,基本上是:
a)在现有模块文件中设置APP_INITIALIZER:
import { APP_INITIALIZER } from '@angular/core';
import { BackendRequestClass } from './backend.request';
import { HttpModule } from '@angular/http';
...
@NgModule({
imports: [
...
HttpModule
],
...
providers: [
...
...
BackendRequestClass,
{ provide: APP_INITIALIZER, useFactory: (config: BackendRequestClass) => () => config.load(), deps: [BackendRequestClass], multi: true }
],
...
});
Run Code Online (Sandbox Code Playgroud)
这些行将在启动应用程序之前从BackendRequestClass类调用load()方法.
如果要使用内置于库中的angular2对后端进行http调用,请确保在"导入"部分中设置"HttpModule".
b)创建一个类并将文件命名为"backend.request.ts":
import { Inject, Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Rx';
@Injectable()
export class BackendRequestClass {
private result: Object = null;
constructor(private http: Http) {
}
public getResult() {
return this.result;
}
public load() {
return new Promise((resolve, reject) => {
this.http.get('http://address/of/your/backend/endpoint').map( res => res.json() ).catch((error: any):any => {
reject(false);
return Observable.throw(error.json().error || 'Server error');
}).subscribe( (callResult) => {
this.result = callResult;
resolve(true);
});
});
}
}
Run Code Online (Sandbox Code Playgroud)
c)要读取后端调用的内容,您只需将BackendRequestClass注入您选择的任何类中并调用getResult().例:
import { BackendRequestClass } from './backend.request';
export class AnyClass {
constructor(private backendRequest: BackendRequestClass) {
// note that BackendRequestClass is injected into a private property of AnyClass
}
anyMethod() {
this.backendRequest.getResult(); // This should return the data you want
}
}
Run Code Online (Sandbox Code Playgroud)
如果这可以解决您的问题,请告诉我.
您可以创建并导出执行工作的函数,而不是让您的入口点本身调用bootstrap:
export function doBootstrap(data: any) {
platformBrowserDynamic([{provide: Params, useValue: new Params(data)}])
.bootstrapModule(AppModule)
.catch(err => console.error(err));
}
Run Code Online (Sandbox Code Playgroud)
您也可以将此函数放在全局对象上,具体取决于您的设置(webpack/SystemJS).它也是AOT兼容的.
当有意义时,这有助于延迟引导程序.例如,在用户填写表单后,将此用户数据作为AJAX调用检索.只需使用此数据调用导出的引导函数即可.
| 归档时间: |
|
| 查看次数: |
44310 次 |
| 最近记录: |