宣布 NgRx 19:NgRx 信号功能、动作信号等等!
我们很高兴地宣布 NgRx 框架的最新主要版本,其中包含一些令人兴奋的新功能、错误修复和其他更新。
更新了 NgRx Signals 功能🚦
NgRx Signals 在 v18 中稳定发布,是一个从头开始构建的新库,具有 Angular Signals、可选的 RxJS 互操作性和开箱即用的实体管理功能。NgRx Signals 库持续获得质量更新和改进,以增强开发人员体验。
新的道具信号存储功能
一个呼声极高的功能是在 SignalStore 创建期间定义其 props。为了支持此功能,withProps
我们添加了一个基本功能,允许将静态属性或可观察对象定义为 SignalStore 成员。
export const BooksStore = signalStore(
withEntities<Book>(),
withRequestStatus(),
withProps(({ isFulfilled }) => ({
fulfilled$: toObservable(isFulfilled).pipe(filter(Boolean)),
})),
);
它还可以用于在一个地方定义所有依赖项:
export const MyStore = signalStore(
withProps(() => ({
service1: inject(Service1),
service2: inject(Service2),
})),
withMethods(({ service1, service2 }) => ({
method1() {
service1.foo();
},
method2() {
service2.bar();
},
}))
);
新withProps
功能与 Angular Signals 的新功能集成在一起,resource
包括linkedSignal
:
const booksStore = signalStore(
withProps(() => {
const bookResource = resource({
loader: () => Promise.resolve({ id: 1, title: "'Lord of the Rings' }),"
});
return {
_bookResource: bookResource,
bookResource: bookResource.asReadonly(),
};
}),
);
以上将 bookResource 公开为只读资源,并保留可写资源。
下一个示例公开prettyTitle
为linkedSignal
,并在内部保持可写状态。
signalStore(
withState({ id: 1, title: "'Lord of the Rings' }),"
withProps((store) => ({
prettyTitle: linkedSignal(() => \`${store.id()}: ${state.store()}\`),
})),
);
新withProps
功能允许您使用 Angular Signals 进一步自定义和扩展 SignalStore。感谢Marko Stanimirović为改进 NgRx Signals 所做的持续努力!
信号方法实用功能
引入实用函数rxMethod
是为了将 RxJS 完成的异步工作连接到 Angular Signals。我们还引入了实用函数,它能让你获得与仅使用信号signalMethod
相同的优势。rxMethod
signalMethod
是一个处理信号或静态值的副作用的工厂函数。
import { Component } from '@angular/core';
import { signalMethod } from '@ngrx/signals';
@Component({ /* ... */ })
export class NumbersComponent {
// 👇 This method will have an input argument
// of type `number | Signal<number>`.
readonly logDoubledNumber = signalMethod<number>((num) => {
const double = num * 2;
console.log(double);
});
}
乍一看,signalMethod
可能与 相同effect
。然而, signalMethod 比 effect 有三个明显的优势:
@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 的“处理器函数”无需注入上下文即可调用。
显式跟踪:仅跟踪参数的信号,而“处理器函数”中的信号则不被跟踪。
阅读文档以了解有关signalMethod 的更多信息。
开发模式检查状态突变
确保状态更新不可变对于 Signal 正确发出并触发必要的 DOM 更新、派生信号或副作用至关重要。为了缓解此问题,该patchState
函数在开发模式下对状态进行了深度冻结。
前:
const userState = signalState(initialState);
patchState(userState, (state) => {
state.user.firstName = 'mutable change'; // mutable change which went through
return state;
});
后:
const userState = signalState(initialState);
patchState(userState, (state) => {
state.user.firstName = 'mutable change'; // throws in dev mode
return state;
});
这确保了状态变化保持不变,从而提供了保留性能和最佳实践的途径。
NgRx Store 支持在信号变化时调度操作
NgRx Store 仍然是 Angular 应用程序中全局状态管理的实际选择。NgRx Store 之前引入了以信号形式选择状态的支持,现在又引入了一种符合人体工程学的方式来调度读取信号的操作。
class BookComponent {
bookId = input.required<number>();
constructor(store: Store) {
store.dispatch(() => loadBook({ id: this.bookId() })));
}
}
该dispatch
方法在初始阶段以及每次bookId
发生更改时执行。如果dispatch
在注入上下文中调用,则信号会被跟踪,直到上下文被销毁。在上面的例子中,销毁就是在上下文BookComponent
被销毁时。
当在dispatch
组件注入上下文之外调用时,信号会在应用程序的整个生命周期内被全局跟踪。为了确保在这种情况下能够正确清理,请将组件的注入器提供给该dispatch
方法:
class BookComponent {
bookId = input.required<number>();
injector = inject(Injector);
store = inject(Store);
ngOnInit() {
// runs outside the injection context
this.store.dispatch(
() => loadBook({ id: this.bookId() }),
{ injector: this.injector }
);
}
}
感谢Rainer Hahnekamp添加这些功能!
NgRx Signals,新的默认设置🤝
NgRx Signals 是一种全新的响应式状态管理方法,并且是 RxJS 的可选组件。它还包含其他实用程序,能够以结构化的方式与 Angular Signals 协同工作,帮助开发者进行扩展。NgRx Signals 现在是推荐集成到 Angular 应用中的本地状态管理库。对于新应用,可以从 NgRx SignalStore 开始。对于现有应用,请考虑迁移到新的@ngrx/signals
软件包。
NgRx 研讨会🎓
随着 NgRx 的使用率与 Angular 的持续增长,许多开发者和团队仍然需要关于如何架构和构建企业级 Angular 应用的指导。我们非常高兴地宣布即将推出由 NgRx 团队直接提供的研讨会!
从二月开始,我们将提供一到三场全天研讨会,涵盖 NgRx 的基础知识到最高级的主题。无论您的团队是刚开始使用 NgRx 还是已经使用一段时间,都能在这些研讨会中学习到新的概念。
研讨会涵盖了使用 NgRx Store 和库的全局状态,以及使用 NgRx ComponentStore 和 NgRx Signals 管理本地状态。
请访问我们的研讨会页面,从即将举行的研讨会列表中进行报名。
新的文档网站💅
新的文档改版正在进行中,它使用AnalogJS从头构建,并将采用全新的设计和更新的内容。这将确保为用户提供最佳体验,并让您更轻松地找到所需信息。此外,它还确保网站更易于维护和更新。由于我们是一个社区驱动的项目,我们始终牢记,网站应该易于贡献。
感谢Mike Ryan为 NgRx 网站新版本所做的工作。
弃用和重大变更💥
此版本包含错误修复、弃用功能和重大变更。对于大多数弃用功能或重大变更,我们提供了迁移功能,该功能会在您将应用升级到最新版本时自动运行。
请参阅版本 19 迁移指南,获取有关迁移到最新版本的完整信息。完整的变更日志可在我们的 GitHub 代码库中找到。
升级到 NgRx 19
要开始使用 NgRx 19,请确保安装以下最低版本:
- Angular 版本 19.x
- Angular CLI 版本 19.x
- TypeScript 版本 5.5.x
- RxJS 版本 ^6.5.x 或 ^7.5.x
NgRx 支持使用 Angular CLIng update
命令来更新你的 NgRx 软件包。要将软件包更新到最新版本,请运行以下命令:
ng update @ngrx/store@19
如果您的项目使用@ngrx/signals
,请运行以下命令:
ng update @ngrx/signals@19
Swag 商店和 Discord 服务器🦺
您可以通过我们的商店购买 NgRx 官方礼品!印有 NgRx 标志的 T 恤有多种尺码、材质和颜色可供选择。我们计划未来在商店中增加贴纸、磁铁等新品。立即访问我们的商店,获取您的 NgRx 礼品吧!
想要与 NgRx 社区新老成员互动的朋友们,欢迎加入我们的Discord 服务器。
为 NgRx 做贡献
我们始终致力于改进文档,并使其始终与 NgRx 框架用户保持同步。为了帮助我们,您可以开始为 NgRx 做出贡献。如果您不确定从哪里开始,请查看我们的贡献指南,并观看Jan-Niklas Wortmann和Brandon Roberts制作的介绍视频 ,它们可以帮助您入门。
感谢我们所有的贡献者和赞助商!
NgRx 始终是一个社区驱动的项目。设计、开发、文档和测试均在社区的帮助下完成。访问我们的社区贡献者页面,查看所有为该框架做出贡献的人员。
如果您有兴趣贡献代码,请访问我们的GitHub页面,浏览我们的未解决问题,其中一些问题已标记为专门针对新贡献者。我们还在 GitHub 上积极讨论新功能和增强功能。
我们要衷心感谢我们的金牌赞助商Nx!Nx 长期以来一直大力推广 NgRx 作为构建 Angular 应用程序的工具,并致力于支持他们所依赖的开源项目。
我们还要感谢我们的铜牌赞助商House of Angular!
在Bluesky、LinkedIn和Twitter上关注我们,了解有关 NgRx 平台的最新更新。
鏂囩珷鏉ユ簮锛�https://dev.to/ngrx/announcing-ngrx-19-ngrx-signals-features-action-signals-and-more-2b35