手记

NGRx 19版本来袭:全新NgRx Signals功能、动作信号等亮点揭晓!

我们非常高兴地向大家宣布NgRx框架的最新重大版本,这个版本包含了一些非常酷的新功能、修复了一些错误和其他更新。

此处省略内容

NgRx Signals 的新功能🚦

NgRx Signals 在 v18 版本中作为稳定版本发布,这是一个从头开始使用 Angular Signals 构建的新库,选择性地与 RxJS 兼容,并内置实体管理功能。NgRx Signals 库持续获得高质量更新和改进,以提升开发者体验。

SignalStore 新特性

用户强烈要求的功能之一是在创建 SignalStore 时定义其 props。为此目的,添加了 withProps 基础特性,允许将静态属性或可观察对象定义为 SignalStore 的成员。

    export const 书籍存储 = signalStore(
      withEntities<书籍>(),
      withRequestStatus(),
      withProps(({ isFulfilled }) => ({
        fulfilled$: toObservable(isFulfilled).pipe(filter(Boolean)),
      })),
    );

进入全屏 退出全屏

它也可以用来定义所有依赖项的地方,或者简化为:它也可以在一处定义所有的依赖项。

    export const 商店 = signalStore(
      withProps(() => ({
        服务1: inject(服务1),
        服务2: inject(服务2),
      })),
      withMethods(({ 服务1, 服务2 }) => ({
        方法一() {
          服务1.foo();
        },
        方法二() {
          服务2.bar();
        },
      }))
    );

全屏模式,退出全屏

新的 withProps 特性与新的 Angular Signals 特性(包括 resourcelinkedSignal)一起使用:

    const booksStore = signalStore(
      withProps(() => {
        const bookResource = resource({
          loader: () => Promise.resolve({ id: 1, title: "'指环王'" }),
        });
        return {
          _bookResource: bookResource,
          bookResource: bookResource.asReadonly(),
        };
      }),
    );

点击全屏/退出全屏

上述将 bookResource 暴露为只读(read-only)资源,并同时保留可写的书资源。

接下来的例子将 prettyTitle 作为 linkedSignal 公开,并在内部保持其可写状态。

    signalStore(
      withState({ id: 1, title: "'<em>魔戒</em>'" }),
      withProps((store) => ({
        prettyTitle: linkedSignal(() => \`${store.id()}: ${state.store()}\`),
      })),
    );

全屏模式,点这里退出

新的 withProps 功能让你可以进一步扩展和完善 SignalStore,即使在使用 Angular Signals 时。感谢 Marko Stanimirović 为 NgRx Signals 的持续改进所做的贡献!

信号处理方法的工具函数

rxMethod 工具函数被引入,旨在提供一种将使用 RxJS 进行的异步任务与 Angular 信号连接的方法。我们还引入了 signalMethod 工具函数,它提供了与 rxMethod 相同的功能,但仅使用信号。

signalMethod 是一个工厂方法,用于处理信号或静态值的处理。

    import { Component } from '@angular/core';
    import { signalMethod } from '@ngrx/signals';

    @Component({ /* ... */ })
    export class NumbersComponent {
      // 👉 这个方法接收一个 `number | Signal<number>` 类型的输入参数。
      readonly logDoubledNumber = signalMethod<number>((num) => {
        const double = num * 2;
        console.log(double);
      });
    }

切换到全屏 退出全屏

乍一看,signalMethodeffect 可能看起来相同。然而,signalMethodeffect 具有三个明显的优势:

@Component({ /* ... */ })
export class NumbersComponent {
  readonly num = signal(2);
  readonly logDoubledNumberEffect = effect(() => {
    console.log(this.num() * 2);
  });
  readonly logDoubledNumber = signalMethod<number>((num) => {
    console.log(num * 2);
  });

  constructor() {
    this.logDoubledNumber(this.num);
  }
}

全屏显示 退出全屏

灵活的输入:输入参数可以是一个静态值,而不仅仅是信号。此外,处理器函数可以多次调用,每次传入不同的输入。
无需注入上下文:与需要注入上下文或注入器的效果不同,处理器函数可以在没有注入上下文的情况下被调用。
显式追踪:只追踪参数的信号,而处理器函数内的信号则不会被追踪。

阅读文档以了解更多关于 signalMethod 的信息。

开发模式检查中的状态变化检查

确保状态更新的不可变性对于Signal发出并触发必要的DOM更新、衍生信号或副作用至关重要。为解决这个问题,在开发环境中,patchState函数会对状态进行深度冻结。

之前 :

    const userState = signalState(initialState);
    patchState(userState, (state) => {
      state.user.firstName = '可变更改'; // 可变更改已生效
      return state;
    });

进入全屏。退出全屏。

然后,

    const userState = signalState(initialState);
    patchState(userState, (state) => {
      state.user.firstName = '可变更'; // 这会在开发模式下抛出错误
      return state;
    });

点击全屏模式下,点击退出全屏

这确保状态变化是不可更改的,从而保持了高性能和最佳实践。

NgRx Store 在信号变化时分发操作

NgRx Store 仍然是 Angular 应用程序中全局状态管理的默认选择之一。NgRx Store 之前引入了将状态作为信号选择的支持,现在提供了一种更人性化的读取信号分发操作的方法。

    class BookComponent {
      书籍ID = input.required<number>();

      constructor(商店: Store) {
        商店.dispatch(() => 加载书籍({ id: this.书籍ID() })));
      }
    }

全屏进入;退出全屏

dispatch 方法首次执行,并且每当 bookId 变化时也会执行。如果在注入上下文中调用 dispatch,信号会被一直跟踪直到该上下文被销毁。在上面提到的例子中,这发生在 BookComponent 被销毁时。

当在组件的注入上下文之外调用 dispatch 时,信号会在整个应用中全局追踪。为了确保在这种情况下能够正确清理资源,需要将组件的 injector 传递给 dispatch 方法:

    class BookComponent {  
      bookId = input.required<number>();
      injector = inject(Injector);
      store = inject(Store);

      ngOnInit() {
        // 在注入上下文之外执行
        this.store.dispatch(
          () => loadBook({ id: this.bookId() }),
          { injector: this.injector }
        );
      }
    }

    // 说明: `loadBook` 方法用于加载指定 ID 的书籍。

全屏切换,退出全屏

感谢Rainer Hahnekamp增加了这些功能!谢谢!

NgRx Signals,新的默认选项 🤝

NgRx Signals 是一种从头开始的方法,用于以反应式方式管理状态,并且它支持可选的RxJS集成。它还提供了一些其他工具,以结构化方式帮助开发人员更好地处理Angular信号。目前,NgRx Signals 是推荐用于Angular应用程序中的本地状态管理库。对于新应用,建议从 NgRx SignalStore 开始。对于现有应用,考虑迁移到新的 @ngrx/signals 包。

NgRx 研讨会 🎓

随着 NgRx 在 Angular 中的使用越来越广泛,许多开发者和团队仍然需要指导来架构和构建企业级 Angular 应用。我们非常高兴地告诉大家,NgRx 团队将直接举办即将举行的研讨会!

从二月开始,我们将提供一到三天的全天工作坊,涵盖从 NgRx 的基础到最前沿的主题。不论您的团队是刚开始接触 NgRx 还是已经使用了一段时间——他们都将在这些工作坊中收获新的概念。

工作坊涵盖了使用NgRx Store和库来管理和维护全局状态,以及使用NgRx ComponentStore和NgRx Signals来管理局部状态。

访问我们的工作坊页面,并从我们即将举办的工作坊列表中报名。

新的文档网来啦 💅

新的文档更新正在进行中,将从头开始使用AnalogJS构建,并采用全新的设计和经过更新的内容。这将确保为我们的用户提供最佳体验,并使用户更容易找到所需的信息。这还将使网站更易于维护和更新。由于我们是社区驱动的项目,我们还确保网站易于贡献。

特别感谢他在[@MikeRyanDev]为NgRx网站新版本做出的努力。

……

废弃和不兼容更改 💥

此版本修复了一些错误,弃用了一些功能,并引入了一些不兼容变更。对于大多数弃用或不兼容变更,我们提供了一个自动迁移工具,它会在您将应用程序升级到最新版本时自动运行。

请查看版本 19 迁移指南,以获取有关迁移到最新版本的所有信息。您可以在我们的 GitHub 仓库中找到完整的CHANGELOG

升级到 NgRx 19 🗓

要开始使用 NgRx 19,请确认安装了以下最低版本(请参阅下方):

Angular 版本 19.x
Angular 命令行工具 版本 19.x
TypeScript 版本 5.5.x
RxJS 版本 6.5.x 或 7.5.x

NgRx 支持使用 Angular CLI 的 ng update 命令来更新 NgRx 包。要更新到最新版本,请运行以下命令:

ng 更新 @ngrx/store@19

全屏显示和退出全屏

如果你的项目使用了@ngrx/signals,执行以下命令就可以了。

ng 更新:@ngrx/signals@19

全屏,退出全屏


潮牌商店和聊天室 🦺

你可以从我们的商店买到官方的 NgRx 周边产品哦!印有 NgRx 标志的 T 恤有多种尺寸、材质和颜色。未来我们还会增加更多周边产品,比如贴纸和磁铁等。快去我们的商店 (访问商店) 选购你的 NgRx 周边产品吧!

加入我们的Discord服务器,与NgRx社区的新老朋友们交流和学习。


为NgRx添砖加瓦 🥰

我们一直在努力改进文档,确保它们始终与 NgRx 框架用户的最新需求保持一致。为了帮助我们,你可以开始为 NgRx 做贡献,比如更新文档、修复问题等。如果你不确定从哪里开始,可以先看一下我们的贡献指南并观看 Jan-Niklas WortmannBrandon Roberts 制作的入门视频,他们可以帮你更好地开始。


感谢所有贡献者和支持者!

NgRx 仍然由社区驱动。设计、开发、文档编写和测试都由社区共同完成。访问我们的社区贡献者部分了解更多贡献者。

如果您想参与贡献,请访问我们的GitHub页面并浏览我们的公开问题,其中一些问题特别标记为适合新手贡献。我们还设有活跃的GitHub讨论,欢迎讨论新功能和增强功能。

我们想向金牌赞助商Nx表示衷心的感谢!Nx一直以来都是NgRx的忠实支持者,致力于支持他们依赖的开源项目,Nx认为NgRx是构建Angular应用的理想工具。

我们还想感谢我们的铜牌赞助商[Angular之家]!

关注我们以获取有关NgRx平台的最新更新,请在BlueskyLinkedInTwitter 上关注我们。

0人推荐
随时随地看视频
慕课网APP