首页 > 解决方案 > 将动态对象传递给角度模块的 forRoot()

问题描述

我正在使用将ngx-cookieconsent模块导入为的包:

const cookieConfig: NgcCookieConsentConfig = { "cookie": { "domain": "localhost" }, ... "theme": "block", "content": { "policy": "Cookie Policy" } }; ... @NgModule({ imports: [ NgcCookieConsentModule.forRoot(cookieConfig) ]

但是,配置上的域属性将在运行时设置,因此我不能将其定义为常量。为了解决这个问题,我做了以下事情:

创建了一个ConfigurationService获取配置并存储它的:

@Injectable()
export class ConfigurationService {

  private configuration: IServerConfiguration;

  constructor(private http: HttpClient, @Inject('BASE_URL') private baseUrl: string) { }

  loadConfig() {
    return this.http.get<IServerConfiguration>(this.baseUrl + 'Configuration')
      .pipe(
        tap(config => {
          this.configuration = <IServerConfiguration>(config);
        })
      )
      .toPromise();
  }

  public domain(): string {
    return this.configuration.domain;
  }
}

并将其设置为,APP_INITIALIZER以便首先调用配置:

export function loadConfiguration(configService: ConfigurationService) {
  return () => configService.loadConfig();
}

...
 providers: [
    ConfigurationService,   
    {
      provide: APP_INITIALIZER,
      useFactory: loadConfiguration,
      multi: true,
      deps: [ConfigurationService]
    }],

然后创建了一个类来使用配置创建我的 cookieConsentOptions 对象:

@Injectable()
export class CookieConstentService {

  cookieDomain: string;

  constructor(configService: ConfigurationService) {
    this.cookieDomain = configService.domain();
  }

  get cookieConstentOptions(): NgcCookieConsentConfig {
    return {
      "cookie": {
        "domain": this.cookieDomain
      },
      "position": "top-right",      
      "content": {
        "message": "This website uses cookies to ensure you get the best experience on our website."
      }
    };
  }

问题

我已经在 configService 和 CookieConstentService 之间建立了依赖关系,因此我只有在拥有配置值时才创建 cookie 选项。

但是,我不确定如何将动态值传递给.forRoot()模块。我应该能够cookieConsentService.cookieConstentOptions()获取对象,但我不确定在哪里实例化它以在模块导入中使用。它需要一个依赖项,所以不能自己创建一个新实例。

任何想法如何有效地将方法注入 3rd 方模块forRoot()

谢谢

标签: angular

解决方案


在发布这个问题后,我了解到传递给forRoot()方法的对象本质上是一个单例,所以如果我在初始化之前设置任何值,那么它将使用它。我实现这个的方式是:

  1. 使用常量/默认设置创建选项的实例(这些不会在环境之间更改):
import { NgcCookieConsentConfig } from "ngx-cookieconsent";

export const cookieConsentOptions: NgcCookieConsentConfig  =
{
  "cookie": {
    "domain": "not-set"
  },
  "position": "bottom-right",
  "theme": "block",
  "palette": {
    "popup": {
      "background": "#df1010",
      "text": "#ffffff",
      "link": "#ffffff"
    },
    "button": {
      "background": "#ffffff",
      "text": "#000000",
      "border": "transparent"
    }
  },
  "type": "info",
  "content": {
    "message": "This website uses cookies to ensure you get the best experience on our website.",
    "dismiss": "Got it!",
    "deny": "Refuse cookies",
    "link": "Learn more",
    "href": "/cookie-policy",
    "policy": "Cookie Policy",
    "target": "_self"
  } 
};

向注入对象APP_INITIALIZER的 appModule添加一个。NgcCookieConsentConfig这将传入上面创建的对象:

...
{
      provide: APP_INITIALIZER,
      useFactory: cookieConfigFactory,
      deps: [HttpClient, NgcCookieConsentConfig, ConfigurationService],
      multi: true
    },
...
  1. 并创建上面使用的方法:
export function cookieConfigFactory(http: HttpClient, config: NgcCookieConsentConfig, configService: ConfigurationService) {
  return () => configService.loadConfig().then(x => config.cookie.domain = x.domain)
}

我从自定义配置服务中获取 cookie 域的值,因此为什么要注入它,你的可能会有所不同。

  1. 最后在appModules中的modules import中,导入第一步创建的对象传入的CookieConsent模块:
NgcCookieConsentModule.forRoot(cookieConsentOptions)

推荐阅读