使用 StoreModule.forRoot 或 StoreModule.forFeature 哪个?

5 ngrx angular

我正在阅读有关内容,他们说 .forRoot 合并所有减速器,当以这种方式操作状态时,您会同时操作所有减速器。

很快,.forFeature 就可以让您操作每个减速器,就好像每个减速器都有一个状态一样。

我想知道以下内容:

1)这是真的吗?

.forFeature()2)多个reducer如何使用?

我收到以下错误:

NullInjectorError: R3InjectorError(AppModule)[StoreFeatureModule -> ReducerManager -> ReducerManager -> ReducerManager]: 
  NullInjectorError: No provider for ReducerManager!
Run Code Online (Sandbox Code Playgroud)

模块

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';

import { environment } from 'environments/environment';
import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { STORE_REDUCERS, STORE_EFFECTS } from './store';

import { AppComponentModule } from '@app/components/app-component.module';
import { AppComponent } from './app.component';

@NgModule({
    declarations: [AppComponent],
    imports: [
        BrowserModule,
        AppComponentModule,
        HttpClientModule,
        StoreDevtoolsModule.instrument({ maxAge: 25, logOnly: !environment.production }),
        StoreModule.forFeature('people', STORE_REDUCERS),
        EffectsModule.forFeature(STORE_EFFECTS),
    ],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)

人员选择器

import { createFeatureSelector, createSelector } from '@ngrx/store';
import { State, adapter } from './people.reducer';

const featureSelector = createFeatureSelector<State>('people');

export const { selectIds, selectEntities, selectAll, selectTotal } = adapter.getSelectors(featureSelector);

export const getLoading = createSelector(featureSelector, ({ loading }) => loading);
export const getError = createSelector(featureSelector, ({ error }) => error);
export const getMain = createSelector(selectAll, (peoples) => peoples.filter((people) => people.isMain)[0]);
Run Code Online (Sandbox Code Playgroud)

店铺索引:

import { ActionReducerMap } from '@ngrx/store';
import * as fromPeopleReducer from './people/people.reducer';
import * as fromPeopleEffects from './people/people.effects';

export interface StoreState {
    people: fromPeopleReducer.State;
}

export const STORE_REDUCERS: ActionReducerMap<StoreState> = {
    people: fromPeopleReducer.reducer,
};

export const STORE_EFFECTS: any[] = [fromPeopleEffects.Effects];
Run Code Online (Sandbox Code Playgroud)

sat*_*ime 11

.forFeature不是 的替代品.forRoot,它是一种如何从延迟加载的模块或导入的库将减速器和效果注入全局存储的方法。

AppModule或在你的根模块中你必须至少有

imports: [
  StoreModule.forRoot({}),
  EffectsModule.forRoot([]),
],
Run Code Online (Sandbox Code Playgroud)

然后在任何其他导入的模块中,您可以添加类似的内容

imports: [
  StoreModule.forFeature('addresses', reducers.addresses),
  StoreModule.forFeature('companies', reducers.companies),
  StoreModule.forFeature('users', reducers.users),
  EffectsModule.forFeature([EntityEffects]),
],
Run Code Online (Sandbox Code Playgroud)

这意味着addresses, companies,users功能将被添加到全球商店中。如果您在多个模块中执行此操作,它仍然会使用相同的功能名称,它不会为每个模块创建存储上下文。减速器也将接收应用程序中所有可用的操作和效果。

.forFeature如果您编写带有库的包,ngrx或者如果没有此模块及其组件,其减速器/效果毫无用处,我建议使用。