@ManfredSteyerManfredSteyerAngular Architectures with Signals
View Slide
@ManfredSteyerSignalas Producer4711Consumerreadsetnotify4712
@ManfredSteyerflights = signal([]);const flights = await this.flightService.findAsPromise(from, to);this.flights.set(flights);
@ManfredSteyerSimpleReactiveBuilding BlockFine-grainedCDZone-less CDInterop withRxJSNo need tounsubscribe
@ManfredSteyer
@ManfredSteyerManfred Steyer
@ManfredSteyer@Injectable({ providedIn: 'root' })export class FlightBookingFacade {[…]private _flights = signal([]);readonly flights = this._flights.asReadonly();async load(from: string, to: string) {const flights = await […];this._flights.set(flights);}}
@ManfredSteyer@Injectable({ providedIn: 'root' })export class FlightBookingFacade {[…]private _flights = signal([]);readonly flights = this._flights.asReadonly();private _from = signal('Hamburg');readonly from = this._from.asReadonly();private _to = signal('Graz');readonly to = this._to.asReadonly();[…]}
@ManfredSteyer@Injectable({ providedIn: 'root' })export class FlightBookingFacade {[…]private state = signal({from: 'Hamburg',to: 'Graz',flights: [] as Flight[], […]});[…]}
@ManfredSteyer@Injectable({ providedIn: 'root' })export class FlightBookingFacade {[…]private state = signal({from: 'Hamburg',to: 'Graz',flights: [] as Flight[], […]});readonly flights = computed(() => this.state().flights);readonly from = computed(() => this.state().from);[…]}
@ManfredSteyerselect(selector)selectSignal(selector)
@ManfredSteyer@Injectable({ providedIn: 'root' })export class FlightBookingFacade {private state = signalState({from: 'Paris',to: 'London',flights: [] as Flight[],basket: {} as Record,});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, to }));}[…]}
@ManfredSteyer@Injectable({ providedIn: 'root' })export class FlightBookingFacade {[…]updateCriteria(from: string, to: string): void {patchState(this.state, updateRoute(from, to));}[…]}function updateRoute(from: string, to: string) {return (state: T) => ({ from, to })}
@ManfredSteyerprivate state = signalState({filter: {from: 'Paris',to: 'London',},flights: [] as Flight[],basket: {} as Record,});filter = this.state.filter();from = this.state.filter.from();to = this.state.filter.to();
@ManfredSteyerexport const FlightBookingStore = signalStore({ providedIn: 'root' },[…]);
@ManfredSteyerexport const FlightBookingStore = signalStore({ providedIn: 'root' },withState({from: 'Paris',to: 'London',[…]}),[…]);
@ManfredSteyerexport const FlightBookingStore = signalStore({ providedIn: 'root' },withState({from: 'Paris',to: 'London',[…]}),withComputed(([…]) => ({ […] })),withMethods(([…]) => ({ })),withHooks({ […] }));
@ManfredSteyerexport const FlightBookingStore = signalStore([…]withMethods((state) => {[…]return {connectCriteria: rxMethod((c$) => c$.pipe([…]))};}),[…]);
@ManfredSteyerexport const FlightBookingStore = signalStore([…]withMethods((state) => {[…]return {connectCriteria: rxMethod((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 }))))};}),[…]);
@ManfredSteyerexport const FlightBookingStore = signalStore([…]withHooks({onInit({ connectCriteria, criteria }) {connectCriteria(criteria);},}),);takes: Signal, Observable, T
@ManfredSteyerexport const FlightBookingStore = signalStore({ providedIn: 'root' },withState({from: 'Paris',to: 'London',[…]}),withSignals(([…]) => ({ […] })),withMethods(([…]) => ({ })),withHooks({ […] }),withCallState());
@ManfredSteyerconst BooksStore = signalStore(withEntities({ collection: 'book' }),withEntities({ collection: 'author' }));
@ManfredSteyerconst BooksStore = signalStore(withLoadEntities(BookService),withLoadEntities(AuthorService),);
@ManfredSteyerFree eBook (5th Edition)ANGULARarchitects.io/bookModule Federation & Nx
@ManfredSteyerServices +SignalsNGRXNGRXSignal StoreDifferentFlavorsrxMethodCustomFeatures
@ManfredSteyerdSlides & Examples Remote Company Workshopsand Consultinghttp://angulararchitects.io