今日已更新 339 条资讯 | 累计 19899 条内容
关于我们

标签:#signals

找到 2 篇相关文章

AI 资讯

Why I Stopped Writing tap() Inside rxResource Streams

There's a pattern I see a lot in Angular codebases that adopted Signals early: a developer discovers rxResource , loves that it handles loading and error state automatically, and then immediately reaches for tap() to write a signal inside the stream. private readonly resource = rxResource ({ params : () => this . paramsSignal (), stream : ({ params }) => this . api . fetch ( params ). pipe ( tap ( data => this . sideSignal . set ( data . meta )) // 💥 ) }); This looks harmless. It runs in development without complaint in zone-based Angular. Then you enable zoneless — or Angular tightens its reactive graph enforcement — and you get NG0600: Writing to signals is not allowed in a reactive context . The rxResource stream runs inside Angular's reactive scheduler. Signal writes there aren't just discouraged — they're illegal by design. The scheduler assumes computed signals and reactive contexts are read-only during evaluation. A write mid-computation breaks the glitch-free guarantee Angular's signal graph is built on. The fix I landed on: make the stream return everything it needs to return, as a single typed value. interface ResourceValue { readonly sections : Section []; readonly meta : Meta ; } private readonly resource = rxResource < ResourceValue , Params > ({ stream : ({ params }) => this . api . fetch ( params ). pipe ( map ( data => ({ sections : transform ( data ), meta : data . meta })) ) }); No tap . No side signal. Everything the rest of the store needs lives in resource.value() and can be read via computed . The lesson isn't "don't use tap". The lesson is that rxResource has a contract: it is a read primitive . Its stream is for fetching and transforming. If you're writing signals inside it, you're treating it as a command bus — and that's a different tool. Originally published on ysndmr.com .

2026-07-08 原文 →
AI 资讯

Signal Forms vs. Reactive Forms: When Should You Upgrade Your Forms? (Angular 22 Guide)

TL;DR — Angular 22 promoted Signal Forms from experimental to stable. This is not "Reactive Forms are dead." It's a real architectural trade-off, and this post walks through both APIs in full, with production-realistic code, so you can decide feature-by-feature instead of framework-war-by-framework-war. Table of Contents Why This Matters Now The Core Question Reactive Forms: Why It Became the Standard Full Example: Reactive Forms Login Where Reactive Forms Still Excel Signal Forms: What Actually Changed in Angular 22 Full Example: Signal Forms Login Where Signal Forms Shine Side-by-Side: Core Concepts Mapped Deep Dive: Validation Synchronous Validation Cross-Field Validation Conditional Validation with when() Async Validation Deep Dive: Dynamic and Nested Forms Nested Form Groups Dynamic Collections (FormArray-style) Deep Dive: Form State — Dirty, Touched, Errors, Submission Developer Experience and Testing Performance Considerations Interop: Migrating Without a Big-Bang Rewrite Migration Strategy for Enterprise Teams When NOT to Migrate Decision Framework FAQ Closing Thoughts Why This Matters Now With Angular 22 (released June 3, 2026), Signal Forms left experimental status and became part of the stable, supported API — alongside resource() and httpResource() . That's a meaningful milestone: it means the Angular team ran extensive internal case studies across real form-heavy applications at Google before committing to stability, and the interop story with Reactive Forms has matured enough that a big-bang rewrite is no longer the only migration path. At the same time, Angular 22 also flips two important defaults: components now use OnPush change detection by default, and zoneless change detection continues its push toward becoming the standard. Signal Forms is part of that same story — Angular's reactivity model finally speaking one dialect end-to-end, from component state to form state to async data. None of this makes Reactive Forms obsolete. It changes what "the

2026-07-07 原文 →