Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Modern State Management in Angular: 3+n Flavors...
Search
Manfred Steyer
PRO
April 10, 2024
Programming
280
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Modern State Management in Angular: 3+n Flavors of the Signal Store @ijs London 2024
Manfred Steyer
PRO
April 10, 2024
More Decks by Manfred Steyer
See All by Manfred Steyer
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
1
370
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
0
170
Nostalgia Meets Technology: Super Mario with TypeScript
manfredsteyer
PRO
0
250
Signal Forms: Details & Live Coding @enterJS 2026 in Mannheim
manfredsteyer
PRO
0
270
Strategic Design in the Frontend: Moduliths & Micro Frontends @DDDEurope
manfredsteyer
PRO
0
190
Agentic UI
manfredsteyer
PRO
0
280
Signal Forms: Beyond the Basics @ngBaguette 2026 in Paris
manfredsteyer
PRO
0
320
Agentic UI beyond Chats Architecture Patterns & Open Standards @ngMunich 05/2026
manfredsteyer
PRO
0
270
Agentic AI in the Frontend: Architectures with Open Standards @iJS London 2026
manfredsteyer
PRO
0
200
Other Decks in Programming
See All in Programming
2年かけて Deno に DOMMatrix を実装した話 / How I implemented DOMMatrix in Deno over two years
petamoriken
0
210
Claude Code全社展開のためにやったことn選~プラグイン302個・コミッター271人を支えるために~
kenchan
5
1.6k
為什麼你並不需要ViewModel / No, you don't need a ViewModel
lovee
1
500
メールのエイリアス機能を履き違えない
isshinfunada
0
240
実装をデザインガイドラインに追従させるための取り組み / 260731-dip-mosh-design-system
dachi023
0
3.9k
「人を評価する AI」の設計と実装
ryoyanara
0
210
AI Engineeringは、AIプロダクトだけのものか? 〜AIがソフトウェアを作る時代の新しい当たり前〜 / No AI in your product. AI Engineering in your development.
rkaga
4
460
【QA Test Talk Vol.8】AI-DLC による Whole Team Approach の加速
pkshadeck
PRO
0
200
5分で問診!Composer セキュリティ健康診断
codmoninc
0
1k
仕様書を書く前にハーネスを作る - Agent Native開発は「探索を速く、判定を固く」
gotalab555
4
1.7k
属人化した知識を、 AIが辿れる地図にする
pkshadeck
PRO
1
190
引き算の組織 ― アウトカムとAIに全振りするために辞めたこと ― / Organization by Subtraction
hirokiyamamoto14
PRO
0
240
Featured
See All Featured
WCS-LA-2024
lcolladotor
0
800
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
Prompt Engineering for Job Search
mfonobong
0
410
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.5k
Navigating Team Friction
lara
192
16k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
250
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
240
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
650
Speed Design
sergeychernyshev
33
2k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.3k
Being A Developer After 40
akosma
91
590k
Transcript
@ManfredSteyer ManfredSteyer Modern State Management in Angular 3+n Flavors of
the Signal Store
@ManfredSteyer Signal as Producer 4711 Consumer read set notify 4712
@ManfredSteyer Signal Eventually Zone-less!
@ManfredSteyer flights = signal<Flight[]>([]); const flights = await this.flightService.findAsPromise(from, to);
this.flights.set(flights); <div *ngFor="let f of flights()"> <flight-card [item]="f" /> </div>
@ManfredSteyer from = signal('Paris'); to = signal('London'); flightRoute = computed(()
=> this.from() + ' to ' + this.to()); constructor() { effect(() => { console.log('from', this.from()); console.log('to', this.to()); }); }
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer Component Store "Intention" Signals sync/ async computed(…) computed(…)
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer Manfred Steyer
@ManfredSteyer
@ManfredSteyer @Injectable({ providedIn: 'root' }) export class FlightBookingFacade { private
state = signalState({ from: 'Paris', to: 'London', flights: [] as Flight[], basket: {} as Record<number, boolean>, }); readonly flights = this.state.flights; readonly from = this.state.from; […] }
@ManfredSteyer @Injectable({ providedIn: 'root' }) export class FlightBookingFacade { […]
readonly selected = computed( () => this.flights().filter((f) => this.basket()[f.id]) ); […] }
@ManfredSteyer @Injectable({ providedIn: 'root' }) export class FlightBookingFacade { […]
updateCriteria(from: string, to: string): void { patchState(this.state, { from, to }) } […] }
@ManfredSteyer @Injectable({ providedIn: 'root' }) export class FlightBookingFacade { […]
updateCriteria(from: string, to: string): void { patchState(this.state, (state) => ({ from: state.to, to: state.from })); } […] }
@ManfredSteyer
@ManfredSteyer export const FlightBookingStore = signalStore( { providedIn: 'root' },
[…] );
@ManfredSteyer export const FlightBookingStore = signalStore( { providedIn: 'root' },
withState({ from: 'Paris', to: 'London', […] }), […] );
@ManfredSteyer export const FlightBookingStore = signalStore( { providedIn: 'root' },
withState({ from: 'Paris', to: 'London', […] }), withComputed(([…]) => ({ […] })), withMethods(([…]) => ({ })), withHooks({ […] }) );
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer export const FlightBookingStore = signalStore( […] withMethods((state) => {
[…] return { connectCriteria: rxMethod<Criteria>((c$) => c$.pipe([…])) }; }), […] );
@ManfredSteyer export const FlightBookingStore = signalStore( […] withMethods((state) => {
[…] return { connectCriteria: rxMethod<Criteria>((c$) => c$.pipe([…])) }; }), […] );
@ManfredSteyer export const FlightBookingStore = signalStore( […] withMethods((state) => {
[…] return { connectCriteria: rxMethod<Criteria>((c$) => c$.pipe( filter(c => c.from.length >= 3 && c.to.length >= 3), debounceTime(300), switchMap((c) => flightService.find(c.from, c.to)), tap(flights => patchState(state, { flights })) )) }; }), […] );
@ManfredSteyer export const FlightBookingStore = signalStore( […] withMethods((state) => {
[…] return { connectCriteria: rxMethod<Criteria>((c$) => c$.pipe( filter(c => c.from.length >= 3 && c.to.length >= 3), debounceTime(300), switchMap((c) => flightService.find(c.from, c.to)), tap(flights => patchState(state, { flights })) )) }; }), […] );
@ManfredSteyer export const FlightBookingStore = signalStore( […] withHooks({ onInit({ connectCriteria,
criteria }) { connectCriteria(criteria); }, }), ); takes: Signal<T>, Observable<T>, T
@ManfredSteyer
@ManfredSteyer const BookingStore = signalStore( withEntities<FlightState>() );
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer Michael Egger-Zikes Rainer Hahnekamp Manfred Steyer
@ManfredSteyer Free eBook (6th Edition) ANGULARarchitects.io/book 20 Chapters 4 new
Signal Store Chapters
@ManfredSteyer Signals: Future of CD Take Care of Data Flow
Stores are the Missing Link Signal Store Lightweight Highly Extensible
@ManfredSteyer
@ManfredSteyer d Slides & Examples Remote Company Workshops and Consulting
http://angulararchitects.io