typescript - 将页面/全局变量传递到 Angular2 应用程序以用于服务

标签 typescript angular angular2-services

我正在寻找一些最佳实践。我的 angular2 应用程序将存在于现有的内容管理系统中。因此,我需要捕获此 CMS 生成的一些“变量”(如身份验证 token 等),并将它们与我的 angular2 应用程序中的 http 请求一起使用。

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

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

<!-- 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>

特别是 $.ServicesFramework 用于生成有效的 http web.api 请求。我想在可以注入(inject)到使用它的每个组件中的服务中捕获它。

例如(我使用的是 typescript ):

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);
        };
    }

}

一个问题是 typescript 编译器抛出找不到“$”等错误。我可以通过在 typescript 类声明之前使用 declare 来强制它工作,如下所示:

//Global Variable Declarations
declare var $: any;
declare var moduleId: any;

问题:

有什么更好的方法(如果存在)来捕获这些“全局”变量以在可良好扩展的应用中使用。


编辑 - 更新到 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) }
]
})

最佳答案

更新 >= RC.6

在 RC.6 中引入了 @NgModule()提供商被添加到那里而不是 boostrap(...). Also provide()` 已弃用并删除,以支持对象文字语法:

在共享库中定义

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

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

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

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

将其注入(inject)到组件、指令、管道或类似服务中

constructor(@Inject(SF) private sf:string) {}

原创

在共享库中定义

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

export let SF = new OpaqueToken('sf');

bootstrap()添加

// import SF from shared library

<罢工>

<罢工>
bootstrap(AppComponent, [
    // other providers
    provide(SF, {useValue: $.ServicesFramework(moduleId)}),
    ]);

<罢工> 想用在什么地方

// import SF from shared library

 constructor(@Inject(SF) private _sf: string){ }

这利用了 Angulars DI 并避免了使代码难以测试的硬编码依赖项。

另见

提示: 而不是 OpaqueToken也可以使用纯字符串。使用 OpaqueToken防止名称冲突,例如,如果它用于许多用户使用的开源包中。如果您控制整个环境,那么您可以确保自己不会发生碰撞,并且使用字符串而不是 OpaqueToken 应该是安全的。 .

更新

InjectionToken引入泛型支持以替换 OpaqueToken现在已弃用。

关于typescript - 将页面/全局变量传递到 Angular2 应用程序以用于服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35215112/

相关文章:

angular - 全局关闭 Material matInput 上的自动完成功能

Angular 9 无法实例化循环依赖!应用程序引用

无法确定类 ManagersService 的模块中的 Angular 2 错误 i

typescript - 如何在 Angular 2(Ionic 2/Angular 2/Typescript)中的服务中注入(inject)服务时传递依赖参数

typescript - 如何访问服务内的全局变量?

angular - routerLink 在 Angular 中不起作用

typescript - 导入整个模块而不重命名

typescript - 类型错误 : Converting circular structure to JSON --> starting at object with constructor 'ClientRequest'

typescript - 如何存储对构造函数的引用?

html - Bootstrap 4 表格响应,水平和垂直滚动