从导出功能访问服务时出现问题 [英] Problem accessing service from export function

查看:53
本文介绍了从导出功能访问服务时出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从导出功能访问我的角度服务.

I want to access my angular service from export function.

我阅读了SO的所有相关问题,但是由于某种原因,解决方案对我不起作用.

I read all the related questions form SO, however for some reason the solutions doesn't work for me.

我添加了app-injector.ts帮助器.看起来像这样:

I added the app-injector.ts helper. It looks like this:

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

/**
 * Allows for retrieving singletons using `AppInjector.get(MyService)` (whereas
 * `ReflectiveInjector.resolveAndCreate(MyService)` would create a new instance
 * of the service).
 */
export let AppInjector: Injector;

/**
 * Helper to set the exported {@link AppInjector}, needed as ES6 modules export
 * immutable bindings (see http://2ality.com/2015/07/es6-module-exports.html) for
 * which trying to make changes after using `import {AppInjector}` would throw:
 * "TS2539: Cannot assign to 'AppInjector' because it is not a variable".
 */
export function setAppInjector(injector: Injector) {
    if (AppInjector) {
        // Should not happen
        console.error('Programming error: AppInjector was already set');
    } else {
        AppInjector = injector;
    }
}

我将注入器添加到AppModule构造函数中,并从其主体中调用SetAppInector,如下所示:

I added the injector to the AppModule constructor and called the SetAppInector from its body like this:

export class AppModule {
    constructor(injector: Injector) {
        setAppInjector(injector);
    }
}

而且,我使用AppInjector将服务注入到我的AppModule中声明的getTranslatedPaginatorIntl()函数中:

And, I use the AppInjector to inject the service in my getTranslatedPaginatorIntl() function that is declared in my AppModule:

export function getTranslatedPaginatorIntl() {
    const translate = AppInjector.get(TranslateService);
    const paginatorIntl = new MatPaginatorIntl();

    paginatorIntl.itemsPerPageLabel = translate.instant('Items per page');
    paginatorIntl.nextPageLabel = translate.instant('Next page');
    paginatorIntl.previousPageLabel = translate.instant('Previous page');
    // paginatorIntl.getRangeLabel = serbianRangeLabel;

    return paginatorIntl;
}

该函数在@NgModule声明的提供者部分中被调用(我想这就是问题所在,因为构造函数可能在此之后被调用,因此不会及时注入Injector):

The function gets called in the providers part of the @NgModule declaration (I guess that's where the problem lies, because the constructor is probably called after this so the Injector doesn't get injected in time):

providers: [
        ApiService,
        LoaderService,
        { provide: MatPaginatorIntl, useValue: getTranslatedPaginatorIntl() },
        { provide: LocationStrategy, useClass: HashLocationStrategy },
        { provide: MAT_DIALOG_DATA, useValue: {} },
        { provide: MatDialogRef, useValue: {} },
    ]

推荐答案

您不需要在注入器周围乱砍-Angular针对您的用例提供了受支持的API.代替 {提供:服务,useValue:someFunc()} ,您可以告诉angular您要使用具有可选依赖项的工厂函数 {提供:服务,useFactory:myFactoryFunc,deps:[MyDepService]} .

You don't need to hack your way around the injector - Angular has a supported API for your use-case. Instead of { provide: Service, useValue: someFunc() } you can tell angular you want to use a factory function with optional dependencies { provide: Service, useFactory: myFactoryFunc, deps: [MyDepService] }.

在您的情况下,它看起来像这样:

In your case it would look something like this:

// The factory function (now with transateService as parameter!)
export const getTranslatedPaginatorIntl = (translateService:TranslateService) => {
    const paginatorIntl = new MatPaginatorIntl();

    paginatorIntl.itemsPerPageLabel = translate.instant('Items per page');
    paginatorIntl.nextPageLabel = translate.instant('Next page');
    paginatorIntl.previousPageLabel = translate.instant('Previous page');

    return paginatorIntl;
}

在您的app.module中:

And in your app.module:

providers: [
    ApiService,
    LoaderService,
    { provide: LocationStrategy, useClass: HashLocationStrategy },
    { provide: MAT_DIALOG_DATA, useValue: {} },
    { provide: MatDialogRef, useValue: {} },
    { 
        provide: MatPaginatorIntl, 
        // The factory function (don't call the function here, angular will do that for you! 
        useFactory: getTranslatedPaginatorIntl, 
        // Provide your dependencies, they will become parameters for the function when angular calls it
        deps: [TranslateService] 
    },
]

有关进一步的解释和详细信息,我建议官方角度文档.

For further explanation and details, I suggest the official angular documentation.

这篇关于从导出功能访问服务时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆