将动态对象传递给角度模块的 forRoot()

ADr*_*ger 6 angular

我使用的包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;
  }
}
Run Code Online (Sandbox Code Playgroud)

这被设置为APP_INITIALIZER首先调用配置:

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

...
 providers: [
    ConfigurationService,   
    {
      provide: APP_INITIALIZER,
      useFactory: loadConfiguration,
      multi: true,
      deps: [ConfigurationService]
    }],
Run Code Online (Sandbox Code Playgroud)

然后创建一个类来使用配置创建我的 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."
      }
    };
  }
Run Code Online (Sandbox Code Playgroud)

问题

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

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

有什么想法可以有效地将方法注入到第三方模块中吗forRoot()

谢谢

ADr*_*ger 3

发布这个问题后,我了解到传递给该方法的对象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"
  } 
};
Run Code Online (Sandbox Code Playgroud)

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

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

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

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