Spartacus:访问 Spartacus.configuration.module.ts 文件内 NgModule 上的 Occ url

发布于 2025-01-11 15:37:37 字数 3866 浏览 0 评论 0原文

我有 Jquery 方面的经验,但 Angular 对我来说很新,斯巴达克斯也是如此。我一直在尝试将我们的斯巴达克斯配置为在多个环境中使用。我能找到的唯一解决方案是在 index.html 上使用元标记,然后根据 janwidmer 和 CarlEricLavoie 提到的 url 获取配置。不过,我确实对这两个解决方案做了一些细微的更改,那就是使用环境。{env}.ts 文件而不是新的后端服务或将配置保留在同一文件的映射中。

我面临的问题是 spartacus.cofniguration.module.ts 文件需要 @NgModule 中的这些值,并且我已经尝试了我能想到的一切,但无法使用 this.config.backend 的值? NgModule 内的 occ?.baseUrl,我需要在其中给出基本 URL 和基本站点的值。

以下是我正在尝试做的事情。我已经编写了逻辑,该逻辑将根据我在环境中收到的 OCC 基本 url 公开正确的配置对象。现在在这里,构造函数内的控制台日志打印了一个包含我需要的所有属性的正确对象,但随后 @NgModule 之前的 conf 对象打印了 undefined 并且 NgModule 内的值也未定义。

我还尝试创建一个新类并将其导入到此处,这样我也许可以创建一个实例,但也无法这样做,因为它需要变量/方法是静态的,以便我能够在内部访问它Ng 模块。

import { Injectable, NgModule } from '@angular/core'; 
import { FacetChangedEvent, FeaturesConfig, I18nConfig, OccConfig, provideConfig, SiteContextConfig } from "@spartacus/core";
import { environment } from '../../environments/environment';
import { defaultB2bCheckoutConfig, defaultB2bOccConfig } from "@spartacus/setup";
import { defaultCmsContentProviders, layoutConfig, mediaConfig } from "@spartacus/storefront";
import { translations } from 'src/assets/i18n-translations/translations';
import { translationChunksConfig } from 'src/assets/i18n-translations/translation-chunks-config';
import { CdcConfig, CdcRootModule, CDC_FEATURE } from '@spartacus/cdc/root';
import { EnvironmentConfigurationModule } from "../../environments/environment-configuration.module"
import { environment  as envdev} from '../../environments/environment';
import { environment as envstag} from '../../environments/environment.stage';
import { environment as envprod} from '../../environments/environment.prod';

let conf : any;
console.log("before ng");
console.log(conf);

@NgModule({
  declarations: [],
  imports: [
  ],
  providers: [provideConfig(layoutConfig), provideConfig(mediaConfig), ...defaultCmsContentProviders, provideConfig(<OccConfig><unknown>{
    
      backend: {
        occ: {
          baseUrl: environment.baseUrl,
        }
      },
    }), provideConfig(<SiteContextConfig>{
    context: {
      urlParameters: ['baseSite', 'language', 'currency'],
      baseSite: [environment?.baseSite],
      currency: ['USD', 'GBP',]
    },
  }),
  provideConfig(<I18nConfig>{
    i18n: {
      backend:{
        loadPath:'assets/i18n-translations/{{lng}}/{{ns}}.ts',
      },
      resources: translations,
      chunks: translationChunksConfig
      ,fallbackLang: 'en'
    },
  }
  ), provideConfig(<FeaturesConfig>{
    features: {
      level: '4.2'
    }
  }), 
  provideConfig(defaultB2bOccConfig), provideConfig(defaultB2bCheckoutConfig), 
]
})
export class SpartacusConfigurationModule { 
  urlValue : string | undefined; 
  env: any;

  constructor(private config: OccConfig) {
        
    this.urlValue = this.config.backend?.occ?.baseUrl;
    
    console.log("baseurl : " + this.config.backend?.occ?.baseUrl);
    
    if(this.urlValue?.includes('s1'))
    { 
      this.env=envstag;   
    }
    else if(this.urlValue?.includes('p1'))
    {
      this.env=envprod; 
    }
    else{
      this.env=envdev; 
    } 
    conf = this.env;
    console.log("conf");
    console.log(conf);
    }

  getConfig() {
   return conf;
  }
}

除了这些解决方案之外,我们还尝试使用 window.location 和 location.href 来查找基本 url 并基于此进行工作。这在本地效果很好,但是一旦将其部署到服务器,它就会说找不到参考窗口/找不到参考位置。我们尝试在 spartacus-configuration.module.ts 内的 NgModule 之前执行此操作

import { environment as envDev } from "../../environments/environment";
import { environment as envStage } from "../../environments/environment.stage";
import { environment as envProd } from "../../environments/environment.prod";
 
let loc=location.hostname;
let env;
if(loc.includes('s1'))
{ 
  env=envStage;   
}
else if(loc.includes('p1'))
{
  env=envProd; 
}
else{
  env=envDev; 
}  
console.log("before ng===>>>",loc); 

I have experience on Jquery but Angular is very new to me and so is spartacus. I have been trying to configure our Spartacus to be used across multiple environments. The only solution that I could find was to use the meta tag on index.html and then grab the config based on url as mentioned by janwidmer and CarlEricLavoie. I did make a slight change from these 2 solutions though, and that was to use the environment.{env}.ts files instead of a new Backend service or keeping the config in a map in the same file.

The issue that I am facing is that the spartacus.cofniguration.module.ts file needs these values in @NgModule and I've tried everything that I could think of, but am unable to use the value of this.config.backend?.occ?.baseUrl inside the NgModule, where I need to give the value for base URL and Base site.

Below is what I am trying to do. i have written the logic that would expose the correct config object according to the OCC base url that I receive on the environment. Now over here, the console log inside the constructor prints a proper object with all the properties I need, but then the conf object right before the @NgModule, it prints undefined and the values inside the NgModule are undefined as well then.

I also tried to create a new class and import it here so I could maybe create an instance, but couldn't do that as well, as it would then need the variable/method to be static for me to be able to access it inside NgModule.

import { Injectable, NgModule } from '@angular/core'; 
import { FacetChangedEvent, FeaturesConfig, I18nConfig, OccConfig, provideConfig, SiteContextConfig } from "@spartacus/core";
import { environment } from '../../environments/environment';
import { defaultB2bCheckoutConfig, defaultB2bOccConfig } from "@spartacus/setup";
import { defaultCmsContentProviders, layoutConfig, mediaConfig } from "@spartacus/storefront";
import { translations } from 'src/assets/i18n-translations/translations';
import { translationChunksConfig } from 'src/assets/i18n-translations/translation-chunks-config';
import { CdcConfig, CdcRootModule, CDC_FEATURE } from '@spartacus/cdc/root';
import { EnvironmentConfigurationModule } from "../../environments/environment-configuration.module"
import { environment  as envdev} from '../../environments/environment';
import { environment as envstag} from '../../environments/environment.stage';
import { environment as envprod} from '../../environments/environment.prod';

let conf : any;
console.log("before ng");
console.log(conf);

@NgModule({
  declarations: [],
  imports: [
  ],
  providers: [provideConfig(layoutConfig), provideConfig(mediaConfig), ...defaultCmsContentProviders, provideConfig(<OccConfig><unknown>{
    
      backend: {
        occ: {
          baseUrl: environment.baseUrl,
        }
      },
    }), provideConfig(<SiteContextConfig>{
    context: {
      urlParameters: ['baseSite', 'language', 'currency'],
      baseSite: [environment?.baseSite],
      currency: ['USD', 'GBP',]
    },
  }),
  provideConfig(<I18nConfig>{
    i18n: {
      backend:{
        loadPath:'assets/i18n-translations/{{lng}}/{{ns}}.ts',
      },
      resources: translations,
      chunks: translationChunksConfig
      ,fallbackLang: 'en'
    },
  }
  ), provideConfig(<FeaturesConfig>{
    features: {
      level: '4.2'
    }
  }), 
  provideConfig(defaultB2bOccConfig), provideConfig(defaultB2bCheckoutConfig), 
]
})
export class SpartacusConfigurationModule { 
  urlValue : string | undefined; 
  env: any;

  constructor(private config: OccConfig) {
        
    this.urlValue = this.config.backend?.occ?.baseUrl;
    
    console.log("baseurl : " + this.config.backend?.occ?.baseUrl);
    
    if(this.urlValue?.includes('s1'))
    { 
      this.env=envstag;   
    }
    else if(this.urlValue?.includes('p1'))
    {
      this.env=envprod; 
    }
    else{
      this.env=envdev; 
    } 
    conf = this.env;
    console.log("conf");
    console.log(conf);
    }

  getConfig() {
   return conf;
  }
}

Apart from these solutions, we have also tried to use window.location and location.href to find the base url and work based on that. This works amazing on local, but as soon as you deploy it to the server, it says that the reference window not found/reference location not found. We tried to do this right before the NgModule, inside spartacus-configuration.module.ts

import { environment as envDev } from "../../environments/environment";
import { environment as envStage } from "../../environments/environment.stage";
import { environment as envProd } from "../../environments/environment.prod";
 
let loc=location.hostname;
let env;
if(loc.includes('s1'))
{ 
  env=envStage;   
}
else if(loc.includes('p1'))
{
  env=envProd; 
}
else{
  env=envDev; 
}  
console.log("before ng===>>>",loc); 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

︶ ̄淡然 2025-01-18 15:37:38

通过环境导入,您的标准构建配置将在部署之前将 environment.ts 变量替换为服务器环境(例如 process.env)设置的变量。因此,您应该只从代码中的 environment.ts 导入,并让服务器处理覆盖临时环境变量。

对于位置和窗口对象,它们无法在构建的服务器端访问,因为 Angular Universal 最初出于 SEO 目的提供了机器人可读的预渲染页面(通常仅是 html)。此实例中不存在位置和窗口对象。在 Angular 中,windowlocation 对象应该导入到您的类中。

使用窗口:https://stackoverflow.com/a/52620181/12566149

使用位置:https://stackoverflow.com/a/43093554/12566149

With environment imports, your standard build configuration will replace the environment.ts variables with the ones set by your server's environment (eg. process.env) before deployment. Therefore, you should only import from environment.ts in your code and let the server handle overriding the staging environment variables.

With location and window objects, they are not accessible on the server-side of the build because Angular Universal initially delivers a pre-rendered page readable by bots (usually html-only) for SEO purposes. The location and window objects do not exist in this instance. In Angular, window and location objects should be imported into your classes.

Use Window: https://stackoverflow.com/a/52620181/12566149

Use Location: https://stackoverflow.com/a/43093554/12566149

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文