将Page/Global Variables传递到Angular2应用程序以与服务一起使用

J K*_*ing 5 typescript angular2-services angular

我在这里寻找一些最好的做法.我的angular2应用程序将存在于现有的内容管理系统中.因此,我需要捕获由此CMS生成的一些"变量"(如auth令牌等),并将其与我的angular2应用程序中的http请求一起使用.

当CMS显示index.html页面时,CMS会对其进行预解析,并在将页面发送到浏览器之前替换一些令牌(即[ModuleContext:ModuleId]).

这是我的index.html页面的示例(abreviated):

<!-- 2. Capture CMS values to pass to app -->
<script type="text/javascript">
    var moduleId = parseInt("[ModuleContext:ModuleId]");
    var portalId = parseInt("[ModuleContext:PortalId]");
    var sf = $.ServicesFramework(moduleId);
</script>

<!-- 3. Configure SystemJS and Bootstrap App-->
<script type="text/javascript">
    System.config({
        packages: {
            //sets the root path of the Angular2 App
            'DesktopModules/KrisisShifts/app': {
                format: 'register',
                defaultExtension: 'js'
            }
        },
        map: { 'app': './app' }
    });
    System.import('app/boot')
            .then(null, console.error.bind(console));
</script>
<shift-app>Loading...</shift-app>
Run Code Online (Sandbox Code Playgroud)

具体来说,$ .ServicesFramework用于生成有效的http web.api请求.我想在一个可以注入到使用它的每个组件中的服务中捕获它.

例如(我正在使用打字稿):

import {Injectable} from 'angular2/core';
import {OnInit} from 'angular2/core';

@Injectable()
export class dnnService implements OnInit{

    sf: any;

    constructor() {}

    ngOnInit() {
        if ($.ServicesFramework) {
            this.sf = $.ServicesFramework(moduleId);
        };
    }

}
Run Code Online (Sandbox Code Playgroud)

一个问题是typescript编译器抛出错误,它无法找到"$"等.我可以通过在typescript类声明之前使用declare来强制执行此操作,如下所示:

//Global Variable Declarations
declare var $: any;
declare var moduleId: any;
Run Code Online (Sandbox Code Playgroud)

题:

什么是捕获这些"全局"变量的更好方法(如果存在),以便在可扩展的应用程序中使用.


编辑 - 更新到RC6

我使用以下内容在RC6中工作:

@NgModule({
declarations: [
    AppComponent,
    FormatDatePipe,
    ShiftPartialPipe 
],
imports: [
    BrowserModule,
    RouterModule.forRoot(AppRoutes),
    FormsModule,
    ReactiveFormsModule,
    HttpModule 
],
bootstrap: [AppComponent],
providers: [
    { provide: LocationStrategy, useClass: HashLocationStrategy },
    { provide: dnnModId, useValue: moduleId },
    { provide: dnnPortalId, useValue: portalId },
    { provide: dnnEditMode, useValue: editMode },
    { provide: dnnSF, useValue: $.ServicesFramework(moduleId) }
]
})
Run Code Online (Sandbox Code Playgroud)

Gün*_*uer 8

更新> = RC.6

在RC.6 @NgModule()中添加了提供程序的引入,而不是在for boostrap(...). Also()中被弃用和删除以支持对象文字语法:

在共享库中定义

import {OpaqueToken} from '@angular/core';

export let SF = new OpaqueToken('sf');
Run Code Online (Sandbox Code Playgroud)
@NgModule({
  providers: [{provide: SF, useValue: $.ServicesFramework(moduleId)},
  directives: [...]
  ...
})
class SomeModule {}
Run Code Online (Sandbox Code Playgroud)

提供者也可以添加到组件和指令中

@Component({
   providers: [
    {provide: SF, useValue: $.ServicesFramework(moduleId)},
   ]);
})
class SomeComponent {}
Run Code Online (Sandbox Code Playgroud)

将其注入组件,指令,管道或服务等

constructor(@Inject(SF) private sf:string) {}
Run Code Online (Sandbox Code Playgroud)

原版的

在共享库中定义

import {OpaqueToken} from '@angular/core';

export let SF = new OpaqueToken('sf');
Run Code Online (Sandbox Code Playgroud)

bootstrap()

// import SF from shared library
Run Code Online (Sandbox Code Playgroud)

bootstrap(AppComponent, [
    // other providers
    provide(SF, {useValue: $.ServicesFramework(moduleId)}),
    ]);
Run Code Online (Sandbox Code Playgroud)

你想在哪里使用它

// import SF from shared library

 constructor(@Inject(SF) private _sf: string){ }
Run Code Online (Sandbox Code Playgroud)

这利用了Angulars DI并避免了硬编码的依赖性,这使得代码难以测试.

也可以看看

提示:OpaqueToken也可以使用普通字符串代替.使用OpaqueToken可防止名称冲突,例如,如果在许多用户使用的开源软件包中使用此名称冲突.如果您控制整个环境,那么您可以确保自己不会发生冲突,并且应该安全地使用字符串而不是OpaqueToken.

更新

InjectionToken引入了泛型支持以替换OpaqueToken现在已弃用的内容.