Javascript 如何将从后端渲染的参数传递到angular2引导方法
有没有办法将后端呈现的参数传递给angular2引导方法?我想使用从后端提供的值为所有请求设置http头。我的Javascript 如何将从后端渲染的参数传递到angular2引导方法,javascript,angular,Javascript,Angular,有没有办法将后端呈现的参数传递给angular2引导方法?我想使用从后端提供的值为所有请求设置http头。我的main.ts文件如下所示: import { bootstrap } from '@angular/platform-browser-dynamic'; import { AppComponent } from "./app.component.ts"; bootstrap(AppComponent); <script> var params = {"token":
main.ts
文件如下所示:
import { bootstrap } from '@angular/platform-browser-dynamic';
import { AppComponent } from "./app.component.ts";
bootstrap(AppComponent);
<script>
var params = {"token": "@User.Token", "xxx": "@User.Yyy"};
System.import('app/main').then((module) => {
module.main(params);
});
</script>
我找到了如何将此参数传递给根组件(),但在激发bootstrap
method时需要它。。。有什么想法吗
编辑:
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'
}
]
}
};
更新2 更新AoT 为了与AoT合作,工厂关闭需要移出
function loadContext(context: ContextService) {
return () => context.load();
}
@NgModule({
...
providers: [ ..., ContextService, { provide: APP_INITIALIZER, useFactory: loadContext, deps: [ContextService], multi: true } ],
另见
更新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 { }
如果不需要等待初始化完成,也可以使用`class AppModule{}的构造函数:
class AppModule {
constructor(/*inject required dependencies */) {...}
}
提示(循环依赖)
例如,注入路由器可能导致循环依赖。
要解决此问题,请注入注入器
,然后通过
this.myDep = injector.get(MyDependency);
而不是直接注入MyDependency
,如:
@Injectable()
export class ConfigService {
private router:Router;
constructor(/*private router:Router*/ injector:Injector) {
setTimeout(() => this.router = injector.get(Router));
}
}
更新
这在RC.5中应该同样适用,但将提供程序添加到根模块的提供程序:[……]
,而不是引导(…)
(我还没有测试过自己)
更新
这里解释了一种完全在角度内完成的有趣方法
您可以使用APP\u初始值设定项
,当
应用程序已初始化,如果函数返回,则延迟它提供的内容
承诺。这意味着该应用程序可以在不进行任何初始化的情况下进行初始化
您还可以使用现有的服务和框架
特征
例如,假设您有一个多租户解决方案,其中
站点信息依赖于提供服务的域名。这个可以
可以是[name].letterpress.com或在上匹配的自定义域
完整主机名。我们可以通过以下方式隐藏这一事实:这是一项承诺的背后
使用APP\u初始值设定项
在引导中:
{provide: APP_INITIALIZER, useFactory: (sites:SitesService) => () => sites.load(), deps:[SitesService, HTTP_PROVIDERS], multi: true}),
sites.service.ts:
@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;
}
或者直接提供准备好的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})]);
唯一的方法是在定义提供者时提供以下值:
bootstrap(AppComponent, [
provide(RequestOptions, { useFactory: () => {
return new CustomRequestOptions(/* parameters here */);
});
]);
然后,您可以在CustomRequestOptions
类中使用这些参数:
export class AppRequestOptions extends BaseRequestOptions {
constructor(parameters) {
this.parameters = parameters;
}
}
如果从AJAX请求中获取这些参数,则需要通过以下方式异步引导:
var appProviders = [ HTTP_PROVIDERS ]
var app = platform(BROWSER_PROVIDERS)
.application([BROWSER_APP_PROVIDERS, appProviders]);
var http = app.injector.get(Http);
http.get('http://.../some path').flatMap((parameters) => {
return app.bootstrap(appComponentType, [
provide(RequestOptions, { useFactory: () => {
return new CustomRequestOptions(/* parameters here */);
}})
]);
}).toPromise();
见这个问题:
import {bootstrap} from '...';
import {provide} from '...';
import {AppComponent} from '...';
export function main(params) {
bootstrap(AppComponent, [
provide(RequestOptions, { useFactory: () => {
return new CustomRequestOptions(params);
});
]);
}
然后,您可以从HTML主页导入它,如下所示:
import { bootstrap } from '@angular/platform-browser-dynamic';
import { AppComponent } from "./app.component.ts";
bootstrap(AppComponent);
<script>
var params = {"token": "@User.Token", "xxx": "@User.Yyy"};
System.import('app/main').then((module) => {
module.main(params);
});
</script>
var params={“token”:“@User.token”,“xxx”:“@User.Yyy”};
System.import('app/main')。然后((模块)=>{
主模块(参数);
});
请参阅此问题:.在Angular2最终版本中,可以使用APP\u初始值设定项提供程序实现您想要的功能 我用一个完整的例子写了一个要点: gist示例是从JSON文件读取,但是可以很容易地更改为从REST端点读取 您需要的基本上是: a) 在现有模块文件中设置APP_初始值设定项:
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 }
],
...
});
在应用程序启动之前,这些行将从BackendRequestClass类调用load()方法
如果要使用angular2内置库对后端进行http调用,请确保在“导入”部分设置“HttpModule”
b) 创建一个类并将文件命名为“backend.request.ts”:
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
}
}
让我知道这是否解决了您的问题。您可以创建并导出一个函数来完成以下工作,而不是让入口点本身调用引导:
export function doBootstrap(data: any) {
platformBrowserDynamic([{provide: Params, useValue: new Params(data)}])
.bootstrapModule(AppModule)
.catch(err => console.error(err));
}
您还可以将此函数放置在全局对象上,具体取决于您的设置(webpack/SystemJS)。它也是AOT兼容的
这有额外的好处来延迟引导,当它有意义的时候。例如,当您在用户填写表单后以AJAX调用的形式检索此用户数据时。只需使用这些数据调用导出的引导函数。但如何将这些参数呈现到typescript文件中?或者我应该在第页的内联脚本中运行这个引导方法吗?但是,当使用es6导入时,如何做到这一点?渲染的确切含义是什么?您是否从服务器生成主HTML文件/JS文件?您是否执行AJAX请求来获取这些参数?我从服务器生成视图。我想我将在后端呈现所有必要的参数,如下所示:
{“token”:“@User.token”,“xxx”:“@User.Yyy”}
因此在呈现的HTML中我将有{“token”:“123abc456def”,“xxx”:“Yyy”}
。我想以某种方式将这个呈现的JSON传递到引导方法中,我在.js文件中有这个方法。有没有办法不用SystemJS运行这个方法(我使用的是webpack,入口点在webpack.config文件中定义)我不是webpack专家,但我可以试试。。。能否添加webpack.config文件的内容?谢谢因此,您希望从HTML中读取。您可以在服务器上添加一个脚本标记,将它们分配给某个全局变量function(){window.headers=someJson;}()
。不确定语法,我自己也不太使用JS。这样你就不必解析了。很好的解决方案,只需给像我这样的未来谷歌用户几句话:1)注意load()
必须返回承诺,而不是可观察的。如果您像我一样在服务中使用可观察对象,请使用.toPromise()
函数。2) 您可能想知道如何将值sites.load()
检索到您的服务、组件等中
export function doBootstrap(data: any) {
platformBrowserDynamic([{provide: Params, useValue: new Params(data)}])
.bootstrapModule(AppModule)
.catch(err => console.error(err));
}