角度aot构建:动态的forRoot参数导致未定义 [英] Angular aot build: dynamic forRoot parameter results in undefined

查看:110
本文介绍了角度aot构建:动态的forRoot参数导致未定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将配置(对象数组)发送到功能模块中的服务,并且此配置需要动态计算.我使用了forRoot,直到我用--aot构建它为止,它都能正常工作.

I need to send a configuration (array of objects) to a service in a feature module and this configuration needs to be dynamically calculated. I used forRoot and it worked fine until I've built it with --aot.

问题:对于--aot,配置结果为undefined.

problem: With --aot, the configuration results in undefined.

这是我在stackblitz上制作的一个示例的链接: https://stackblitz.com/edit/angular-aot-forroot-error

Here is a link to an example I made on stackblitz: https://stackblitz.com/edit/angular-aot-forroot-error

!!它可以在stackblitz上工作,因为它不是用aot构建的!但是,如果用aot在本地构建它,则GetConfigService将抛出错误,因为config将是未定义的.

!! it works as desired on stackblitz, since it is not built with aot !! If you build it locally with aot, though, the GetConfigService will throw an error since config will be undefined.

重要部分:

AppModule:

AppModule:

export const config = [
  {
    id: 'first'
  },
  {
    id: 'second'
  }
];

// just illustrative modification (in my project I need to modify config based on environment)
export function modifyConfig(config) {
  return config.map(c => c.id === 'first' ? {...c, default: true} : c);
}

const configModified = modifyConfig(config);

@NgModule({
  imports:      [
    BrowserModule,
    WithParametersdModule.forRoot(configModified)
  ],
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

WithParametersdModule:

WithParametersdModule:

@NgModule()
export class WithParametersdModule {
  static forRoot(config) {
    return {
      ngModule: WithParametersdModule,
      providers: [
        {
          provide: SOME_CONFIG,
          useValue: config
        },
        GetConfigService
      ]
    }
  }
}

GetConfigService:

GetConfigService:

@Injectable()
export class GetConfigService {

  constructor(@Inject(SOME_CONFIG) private config) {}

  get configObj() {
    if (!this.config) {
      throw `config: ${this.config}`;
    }

    return this.config;
  }
}

感谢帮助或我做错了什么解释.

Thanks for help or explanation of what am I doing wrong.

推荐答案

我发现这可能是因为AOT会在编译时尝试替换useValue,但是当您在运行时传递这些值时,AOT只是将它替换为undefined.解决方法是使用useFactory而不是useValue.这样就解决了这个问题.

I found that it might be because AOT would try to replace useValue at compile time but when you pass these values at runtime so AOT just replace it with undefined. The solution is use useFactory instead of useValue. This solved this problem.

这是我所做的:

// Declare a function type which returns the config
export type ConfigFunction = () => any;

// Replace useValue with useFactory
@NgModule()
export class WithParametersdModule {
  static forRoot(config: {
    func: ConfigFunction,
    // You could add other config parameters here...
  }) {
    return {
      ngModule: WithParametersdModule,
      providers: [
        {
          provide: SOME_CONFIG,
          useFactory: config.func
        },
        GetConfigService
      ]
    }
  }
}

然后您可以按以下方式使用它:

Then you can use it as following:

export function getConfig(): any {
  return {
    id: 'first'
  },
  {
    id: 'second'
  };
}

@NgModule({
  // ...
  imports: [
    BrowserModule,
    WithParametersdModule.forRoot({ func: getConfig }),
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

这篇关于角度aot构建:动态的forRoot参数导致未定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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