Угловая сборка: динамический параметр forRoot приводит к неопределенному - PullRequest
0 голосов
/ 02 мая 2018

Мне нужно отправить конфигурацию (массив объектов) службе в функциональном модуле, и эта конфигурация должна быть рассчитана динамически. Я использовал forRoot, и он работал нормально, пока я не собрал его с --aot.

проблема: При --aot конфигурация приводит к undefined.

Вот ссылка на пример, который я сделал на stackblitz: https://stackblitz.com/edit/angular-aot-forroot-error

!! он работает так, как нужно для стекаблица, так как он не построен с помощью aot !! Если вы создадите его локально с помощью aot, GetConfigService выдаст ошибку, поскольку config будет неопределенным.

Важные части:

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:

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

GetConfigService:

@Injectable()
export class GetConfigService {

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

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

    return this.config;
  }
}

Спасибо за помощь или объяснение того, что я делаю неправильно.

1 Ответ

0 голосов
/ 28 октября 2018

Я обнаружил, что это может быть из-за того, что AOT попытается заменить useValue во время компиляции, но когда вы передадите эти значения во время выполнения, AOT просто заменит его на undefined. Решение - использовать useFactory вместо useValue. Это решило эту проблему.

Вот что я сделал:

// 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
      ]
    }
  }
}

Тогда вы можете использовать его следующим образом:

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

@NgModule({
  // ...
  imports: [
    BrowserModule,
    WithParametersdModule.forRoot({ func: getConfig }),
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...