我有一个angular-cli
生成的项目,我希望与deployd后端一起使用。 Deployd提供了一个脚本,用于访问可以从http://<deployd-host>/dpd.js
加载的API。这会创建一个全局dpd
对象,可以从javascript全局上下文访问API(例如,从Chrome开发工具控制台)。
我想将它包装在Angular2服务中,以便我可以注入一个用于测试等的模拟。任务是从URL加载脚本,然后获得对全局dpd
对象的访问权限。我看过this SO帖子,但未能得到公认的答案。如果我手动将脚本添加到document
对象,则无法访问window
上的dpd对象。
此外,从中加载脚本的URL将根据环境而不同,例如本地开发人员http://localhost:3000/dpd.js
,暂存http://dev.example.com/dpd.js
和生产http://www.example.com/dpd.js
。理想情况下,我也可以在服务中配置它。
寻找下面的工作。
@Injectable()
export class DpdService {
constructor() {
if (getEnvironmentSomeHow() == 'development') {
loadScriptFrom("http://localhost:3000/dpd.js");
} else {
loadScriptFrom("http://dev.example.com/dpd.js");
}
dpd = window.dpd;
}
public session(): Observable<Session> {
return Observable.fromPromise(dpd.sessions.get());
}
}
答案 0 :(得分:1)
应用程序环境完全取决于开发人员的选择。这些可以是有条件地包含依赖于Node环境变量的TS文件。它可以是根据客户端全局变量定义Angular提供程序的单个文件(可能由Webpack DefinePlugin
或EnvironmentPlugin
提供,例如,请参阅angular2-webpack-starter
)。在最简单的形式中,它只是客户端全局ENV
变量,所有决策都是就地制定的 - 甚至可以使用服务器端模板在HTML中设置:
<script>
window.ENV = <% SERVER_SIDE_ENV_VARIABLE %>
</script>
由于脚本应该在应用程序初始化时加载,因此必须在APP_INITIALIZER
多提供程序中加载:
...
import {APP_INITIALIZER} from '@angular/core'
import {DOCUMENT} from '@angular/platform-browser'
@Injectable()
export class DpdService {
dpd: any;
constructor(@Inject(DOCUMENT) document: Document) {}
load() {
const srcBase = window.ENV === 'dev'
? 'http://localhost:3000/'
: 'http://dev.example.com/';
const script = this.document.createElement('script');
this.document.body.appendChild(script);
return new Promise((resolve, reject) => {
script.onload = resolve;
script.onerror = reject;
script.async = true;
script.src = srcBase + 'dpd.js';
}).then(() => {
this.dpd = window.dpd;
});
}
session(): Observable<Session> {
return Observable.fromPromise(this.dpd.sessions.get());
}
}
export function dpdAppInitializerFactory(dpdService: DpdService) {
return () => dpdService.load();
}
...
providers: [
DpdService,
{
provide: APP_INITIALIZER,
useFactory: dpdAppInitializerFactory,
deps: [DpdService],
multi: true
}
],
...
在初始化应用时,load
方法的承诺已完成,且dpd
属性已设置。