发布于 2026-01-06 0 阅读
0

NgRx 特征创建器

NgRx 特征创建器

封面照片由Sigmund拍摄,来自 Unsplash。

createFeature函数在 NgRx v12.1 中引入。
它通过为每个要素状态属性生成要素选择器及其子选择器,从而减少选择器文件中的重复代码。其设计灵感来源于ngrx-child-selectors库。

NgRx 功能

全局状态管理主要由三个基本构建模块组成@ngrx/store:actions、reducer 和 selector。对于特定的特性状态,我们会创建一个 reducer 来处理基于已分发 action 的状态转换,并使用 selector 来获取特性状态的切片。此外,我们还需要定义一个特性名称,以便在 NgRx store 中注册特性 reducer。因此,我们可以将 NgRx 特性视为特定特性状态的特性名称、特性 reducer 和 selector 的组合。接下来,我们来看看创建 NgRx 特性的“传统”方法。

要创建 reducer,可以使用createReducer@ngrx/store包中的函数:

// books.reducer.ts
import { createReducer } from "@ngrx/store";

import * as BookListPageActions from "./book-list-page.actions";
import * as BooksApiActions from "./books-api.actions";

export const featureName = "books";

export interface State {
  books: Book[];
  loading: boolean;
}

const initialState: State = {
  books: [],
  loading: false,
};

export const reducer = createReducer(
  initialState,
  on(BookListPageActions.enter, (state) => ({
    ...state,
    loading: true,
  })),
  on(BooksApiActions.loadBooksSuccess, (state, { books }) => ({
    ...state,
    books,
    loading: false,
  }))
);
Enter fullscreen mode Exit fullscreen mode

要将此 reducer 注册到 NgRx store 中,我们使用以下StoreModule.forFeature方法:

// books.module.ts
import { StoreModule } from "@ngrx/store";

import * as fromBooks from "./books.reducer";

@NgModule({
  imports: [
    StoreModule.forFeature(fromBooks.featureName, fromBooks.reducer),
  ],
})
export class BooksModule {}
Enter fullscreen mode Exit fullscreen mode

为了从数据存储中选择状态,我们创建一个特性选择器、子选择器以及一个视图模型选择器:

// books.selectors.ts
import { createFeatureSelector, createSelector } from "@ngrx/store";

import * as fromBooks from "./books.reducer";

// feature selector
export const selectBooksState = createFeatureSelector<fromBooks.State>(
  fromBooks.featureKey
);

// child selectors
export const selectBooks = createSelector(
  selectBooksState,
  (state) => state.books
);
export const selectLoading = createSelector(
  selectBooksState,
  (state) => state.loading
);

// view model selector
export const selectBookListPageViewModel = createSelector(
  selectBooks,
  selectLoading,
  (books, loading) => ({ books, loading })
);
Enter fullscreen mode Exit fullscreen mode

使用功能创建器

现在我们来看看如何使用该createFeature函数实现同样的结果。首先,我们将重构 reducer 文件:

// `createFeature` is imported from `@ngrx/store`
import { createFeature, createReducer } from "@ngrx/store";

import * as BookListPageActions from "./book-list-page.actions";
import * as BooksApiActions from "./books-api.actions";

interface State {
  books: Book[];
  loading: boolean;
}

const initialState: State = {
  books: [],
  loading: false,
};

// feature name and reducer are now passed to `createFeature`
export const booksFeature = createFeature({
  name: "books",
  reducer: createReducer(
    initialState,
    on(BookListPageActions.enter, (state) => ({
      ...state,
      loading: true,
    })),
    on(BooksApiActions.loadBooksSuccess, (state, { books }) => ({
      ...state,
      books,
      loading: false,
    }))
  ),
});
Enter fullscreen mode Exit fullscreen mode

现在可以通过将整个特征对象传递给该StoreModule.forFeature方法,在 store 中注册特征 reducer:

// books.module.ts
import { StoreModule } from "@ngrx/store";
import { booksFeature } from "./books.reducer";

@NgModule({
  imports: [StoreModule.forFeature(booksFeature)],
})
export class BooksModule {}
Enter fullscreen mode Exit fullscreen mode

最后,我们来看看选择器文件长什么样:

// books.selectors.ts
import { createSelector } from "@ngrx/store";
import { booksFeature } from "./books.reducer";

export const selectBookListPageViewModel = createSelector(
  booksFeature.selectBooks,
  booksFeature.selectLoading,
  (books, loading) => ({ books, loading })
);
Enter fullscreen mode Exit fullscreen mode

之前手动创建的要素选择器和子选择器现已移除,因为createFeature系统会自动生成它们。所有生成的选择器都带有“select”前缀,要素选择器带有“State”后缀。

在这个例子中,特征选择器的名称是 `<feature selector>` selectBooksState,其中“books”是特征名称。子选择器的名称selectBooks分别是 `<child selector>` 和selectLoading`<child selector>`,它们分别基于书籍特征状态的属性名称。

结论

特性创建者可以利用 TypeScript v4.1 中引入的模板字面量类型来减少选择器文件中的重复代码。这可以极大地改进你的代码,尤其是在处理大型特性状态时。

资源

同行评审员

谢谢 Tim 为我这篇文章提出的宝贵建议!


《NgRx 功能创建器》指南现已发布在 NgRx 官方文档中。点击此处了解更多信息。

文章来源:https://dev.to/this-is-angular/ngrx-feature-creator-2c72