且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

通过页/全局变量到Angular2应用与服务的使用

更新时间:2023-10-25 22:09:40

在共享库定义

 进口{} OpaqueToken从'angular2 /核心;出口让SF =新OpaqueToken('科幻');

引导()添加

  //进口SF从共享库引导(AppComponent,[
    //其他供应商
    提供(SF,{useValue:$ .ServicesFramework(的moduleId)})
    ]);

如果你想使用它

  //进口SF从共享库 构造函数(@注入(SF)私人_sf:字符串){}

这利用Angulars DI,避免硬codeD的依赖使得code难以测试。

另请参见

I am looking for some best practice here. My angular2 app will live inside an existing Content Managment System. As a result I need to capture some "variables" generated by this CMS (like auth tokens etc) and use them with http requests inside my angular2 app.

When the index.html page is displayed by the CMS it is pre-parsed by the CMS and some tokens (ie [ModuleContext:ModuleId]) are replaced before the page is sent to the browser.

Here is an example of my index.html page (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>

Specifically the $.ServicesFramework is used for generating valid http web.api requests. I want to capture this in a service that can be injected into each component that uses it.

for example (I am using 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);
        };
    }

}

One problem is that the typescript compiler throws error that it cannot find "$" etc. I can force this to work by using declare before the typescript class declaration like the following:

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

Question:

What is a better way (if exists) of capturing these "global" variable for use in the app that will scale well.

In a shared library define

import {OpaqueToken} from 'angular2/core';

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

In bootstrap() add

// import SF from shared library

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

Where you want to use it

// import SF from shared library

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

This utilizes Angulars DI and avoids hardcoded dependencies which makes the code hard to test.

See also