Поставщик Angular2, который зависит от других поставщиков

У меня есть несколько модулей в моем приложении Angular2, которые предоставляют услуги и конфигурацию.

Теперь я хотел бы включить @ngrx/store, который собирает доступные редукторы из моих модулей.


Вот загрузочный код:

import {OpaqueToken} from 'angular2/core'
import {provideStore} from '@ngrx/store'

export const REDUCER_TOKEN = new OpaqueToken('Reducer');

bootstrap(AppComponent, [
    provide(REDUCER_TOKEN, { useClass: Module1Reducers, multi: true }),
    provide(REDUCER_TOKEN, { useClass: Module2Reducers, multi: true }),
    // old code: provideStore({module1, module2}, {module1:{}, module2:[]})
    provideStore(/* INSERT CODE HERE */)
]);

Комментарий INSERT CODE HERE следует заменить чем-то, что использует все REDUCER_TOKEN провайдеры.

Как я могу этого добиться?


person Benjamin M    schedule 27.03.2016    source источник
comment
видишь provide(REDUCER_TOKEN, ...)? Это провайдер, который можно использовать вместе с @Inject(REDUCER_TOKEN) list:MyInterface[]. Посмотрите здесь ( blog.thoughtram .io/angular2/2015/11/23/ ), раздел Общие сведения о мультипровайдерах.   -  person Benjamin M    schedule 31.03.2016


Ответы (1)


Я не вижу способа передать его provideStore() напрямую.

provideStore создает и возвращает массив провайдеров. Моя попытка состоит в том, чтобы сначала добавить поставщиков, которые создает provideStore(), а затем на втором этапе переопределить REDUCER, который зависит от REDUCER_TOKEN:

bootstrap(AppComponent, [
    provide(REDUCER_TOKEN, { useClass: Module1Reducers, multi: true }),
    provide(REDUCER_TOKEN, { useClass: Module2Reducers, multi: true }),
    // add generated providers
    provideStore(),
    // override `REDUCER` provider
    provide(REDUCER, {
      deps: [REDUCER_TOKEN],
      useFactory(reducer){
        if(typeof reducer === 'function'){
          return reducer;
        }

        return combineReducers({
            "foo":reducer[0].reducerFunction, 
            "bar":reducer[1].reducerFunction
        });
      }
    }),
]);

Если для одного и того же токена (или типа) добавлено несколько поставщиков без multi: true, то действует только тот, который был добавлен последним.

Построен в соответствии с этой provideStore() реализацией https://github.com/ngrx/store/blob/master/src/ng2.ts#L56

-- не испытано --

person Günter Zöchbauer    schedule 31.03.2016
comment
Благодарю вас! Теперь я проверил его, и он работает с некоторыми небольшими изменениями: в useFactory(reducer) reducer это массив: [Module1, Module2]. Но функция combineReducers будет принимать только функции в качестве параметра. Хотя для получения хороших названий магазинов вам нужно построить объект из массива reducers. В итоге параметр, передаваемый combineReducers, должен выглядеть так: {"foo":reducer[0].reducerFunction, "bar":reducer[1].reducerFunction} (где foo и bar — названия магазинов). ... в любом случае: Вы решили это! Спасибо. - person Benjamin M; 01.04.2016
comment
Выглядит хорошо, в моем коде я использую более динамичное решение, где я получаю name и reducerFunction из массива модулей. Вот так: return combineReducers(reducer.reduce((o, v) => { o[v.name] = v.reducerFunction; return o; }, {}));. Но ваш код тоже в порядке :) - person Benjamin M; 03.04.2016
comment
Большой. Тогда я оставлю все как есть, ваш комментарий все равно останется здесь. - person Günter Zöchbauer; 03.04.2016