
рдХрднреА-рдХрднреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рд╕рд░рд▓рддрдо рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЕрдВрддрддрдГ рдЕрдЪреНрдЫреЗ рд╕реЗ рдЕрдзрд┐рдХ рд╕рдорд╕реНрдпрд╛рдПрдВ рдкреИрджрд╛ рдХрд░рддрд╛ рд╣реИ, рдХреЗрд╡рд▓ рдХрд╣реАрдВ рдФрд░ рдЬрдЯрд┐рд▓рддрд╛ рдмрдврд╝ рдЬрд╛рддреА рд╣реИред рдЕрдВрддрд┐рдо рдкрд░рд┐рдгрд╛рдо рдПрдХ рджрд╛рдВрддреЗрджрд╛рд░ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рд╣реИ рдЬрд┐рд╕реЗ рдХреЛрдИ рдЫреВрдирд╛ рдирд╣реАрдВ рдЪрд╛рд╣рддрд╛ рд╣реИред
рдЕрдиреБрд╡рд╛рджрдХ рдХреЗ рдиреЛрдЯреНрд╕рд▓реЗрдЦ 2017 рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдЖрдЬ рддрдХ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИред рдпрд╣ RxJS рдФрд░ Ngrx рдореЗрдВ рдЕрдиреБрднрд╡реА рд▓реЛрдЧреЛрдВ рдХреЗ рдЙрджреНрджреЗрд╢реНрдп рд╕реЗ рд╣реИ, рдпрд╛ рдЬреЛ Angular рдореЗрдВ Redux рдХреЛ рдЖрдЬрд╝рдорд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред
рдХреЛрдб рд╕реНрдирд┐рдкреЗрдЯ рдХреЛ рд╡рд░реНрддрдорд╛рди RxJS рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЕрджреНрдпрддрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдкрдардиреАрдпрддрд╛ рдФрд░ рд╕рдордЭ рдореЗрдВ рдЖрд╕рд╛рдиреА рдХреЛ рдмреЗрд╣рддрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдереЛрдбрд╝рд╛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
Ngrx / store рдПрдХ рдХреЛрдгреАрдп рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИ рдЬреЛ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдХрд╛рд░реНрдпреЛрдВ рдХреА рдЬрдЯрд┐рд▓рддрд╛ рдХреЛ рд╕рдорд╛рд╣рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИред рдПрдХ рдХрд╛рд░рдг рдпрд╣ рд╣реИ рдХрд┐ ngrx / store рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЛ рдЧрд▓реЗ рд▓рдЧрд╛рддрд╛ рд╣реИ, рдЬреЛ рдпрд╣ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЕрдВрджрд░ рдХреНрдпрд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЗрд╕рдХреЗ рдмрд╛рд╣рд░ рдЕрдзрд┐рдХ рддрд░реНрдХ-рд╡рд┐рддрд░реНрдХ рд╣реЛ рд╕рдХреЗред Ngrx / store рдореЗрдВ, reducers (рдмрд╛рдж рдореЗрдВ reducers рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрджрд░реНрднрд┐рдд), рдЪрдпрдирдХрд░реНрддрд╛ (рдмрд╛рдж рдореЗрдВ selectors рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрджрд░реНрднрд┐рдд) рдФрд░ RxJS рдСрдкрд░реЗрдЯрд░ рдЬреИрд╕реА рдЪреАрдЬреЗрдВ рд╢реБрджреНрдз рдХрд╛рд░реНрдп рд╣реИрдВред
рд╢реБрджреНрдз рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг, рдбрд┐рдмрдЧ, рд╡рд┐рд╢реНрд▓реЗрд╖рдг, рд╕рдорд╛рдирд╛рдВрддрд░ рдФрд░ рд╕рдВрдпреЛрдЬрди рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИред рдПрдХ рд╕рдорд╛рд░реЛрд╣ рд╕рд╛рдл рд╣реИ рдЕрдЧрд░:
- рдПрдХ рд╣реА рдЗрдирдкреБрдЯ рдХреЗ рд╕рд╛рде, рдпрд╣ рд╣рдореЗрд╢рд╛ рдПрдХ рд╣реА рдЖрдЙрдЯрдкреБрдЯ рджреЗрддрд╛ рд╣реИ;
- рдХреЛрдИ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯ рдирд╣реАрдВред
рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯреНрд╕ рд╕реЗ рдмрдЪрд╛ рдирд╣реАрдВ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╡реЗ ngrx / store рдореЗрдВ рдЕрд▓рдЧ-рдерд▓рдЧ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдмрд╛рдХреА рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рд╢реБрджреНрдз рдХрд╛рд░реНрдп рд╢рд╛рдорд┐рд▓ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред
рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯ
рдЬрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рдкрддреНрд░ рд╕рдмрдорд┐рдЯ рдХрд░рддрд╛ рд╣реИ, рддреЛ рд╣рдореЗрдВ рд╕рд░реНрд╡рд░ рдкрд░ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рд╕рд░реНрд╡рд░ рдХреЛ рдмрджрд▓рдирд╛ рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рдЬрд╡рд╛рдм рджреЗрдирд╛ рдПрдХ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯ рд╣реИред рдЗрд╕ рдШрдЯрдХ рдореЗрдВ рд╕рдВрднрд╛рд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
this.store.dispatch({ type: 'SAVE_DATA', payload: data, }); this.saveData(data)
рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рд╣рдо рдШрдЯрдХ рдХреЗ рдЕрдВрджрд░ рдХреЗрд╡рд▓ рдПрдХреНрд╢рди (рдЗрд╕рдХреЗ рдмрд╛рдж рдХреА рдХрд╛рд░реНрд░рд╡рд╛рдИ) рдХреЛ рднреЗрдЬ рд╕рдХрддреЗ рд╣реИрдВ рдЬрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдлреЙрд░реНрдо рд╕рдмрдорд┐рдЯ рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯ рдХреЛ рдХрд╣реАрдВ рдФрд░ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИред
Ngrx / рд╕реНрдЯреЛрд░ рдореЗрдВ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЗ рд▓рд┐рдП Ngrx / рдЗрдлреЗрдХреНрдЯреНрд╕ рдорд┐рдбрд▓рд╡реЗрдпрд░ рд╣реИред рдпрд╣ рджреЗрдЦрдиреЗ рдпреЛрдЧреНрдп рдереНрд░реЗрдб рдореЗрдВ рд╕рдмрдорд┐рдЯ рдХреА рдЧрдИ рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рд╕реБрдирддрд╛ рд╣реИ, рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯреНрд╕ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рддреБрд░рдВрдд рдпрд╛ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд░реВрдк рд╕реЗ рдирдП рдПрдХреНрд╢рди рджреЗрддрд╛ рд╣реИред рд▓реМрдЯреА рд╣реБрдИ рдХрд╛рд░реНрд░рд╡рд╛рдЗрдпрд╛рдБ reducer рдХреЛ рджреА рдЬрд╛рддреА рд╣реИрдВред
RxJS рддрд░реАрдХреЗ рд╕реЗ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯреНрд╕ рдХреЛ рд╣реИрдВрдбрд▓ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХреЛрдб рдХреЛ рдХреНрд▓реАрдирд░ рдмрдирд╛рддреА рд╣реИред рдШрдЯрдХ рд╕реЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдХрд╛рд░реНрд░рд╡рд╛рдИ SAVE_DATA
рднреЗрдЬрдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдк рдмрд╛рдХреА рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░рднрд╛рд╡ рд╡рд░реНрдЧ рдмрдирд╛рддреЗ рд╣реИрдВ:
@Effect() saveData$ = this.actions$.pipe( ofType('SAVE_DATA'), pluck('payload'), switchMap(data => this.saveData(data)), map(res => ({ type: 'DATA_SAVED' })), );
рдпрд╣ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рднреЗрдЬрдиреЗ рдФрд░ рдЕрд╡рд▓реЛрдХрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рджрд╕реНрдпрддрд╛ рд▓реЗрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдШрдЯрдХ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЛ рд╕рд░рд▓ рдХрд░рддрд╛ рд╣реИред
Ngrx / рдкреНрд░рднрд╛рд╡реЛрдВ рдХрд╛ рджреБрд░реБрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рдЖрд╕рд╛рди рд╣реИ
Ngrx / рдкреНрд░рднрд╛рд╡ рдПрдХ рдмрд╣реБрдд рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╕рдорд╛рдзрд╛рди рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХрд╛ рджреБрд░реБрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИред рдпрд╣рд╛рдБ рдХреБрдЫ рд╕рд╛рдорд╛рдиреНрдп ngrx / рд╕реНрдЯреЛрд░ рд╡рд┐рд░реЛрдзреА рдкреИрдЯрд░реНрди рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ Ngrx / рдкреНрд░рднрд╛рд╡ рд╕рд░рд▓ рдХрд░рддрд╛ рд╣реИ:
1. рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рд╕реНрдерд┐рддрд┐
рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдЖрдк рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд▓реНрдЯреАрдореАрдбрд┐рдпрд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдкрд░ рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдФрд░ рдЖрдкрдХреЗ рдкрд╛рд╕ рд░рд╛рдЬреНрдп рдХреЗ рдкреЗрдбрд╝ рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЧреБрдг рд╣реИрдВ:
export interface State { mediaPlaying: boolean; audioPlaying: boolean; videoPlaying: boolean; }
рдЪреВрдВрдХрд┐ рдСрдбрд┐рдпреЛ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдореАрдбрд┐рдпрд╛ рд╣реИ, рдЬрдм рднреА audioPlaying
рд╕рд╣реА рд╣реЛрддреА рд╣реИ, mediaPlaying
рднреА рд╕рд╣реА рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред рддреЛ рдпрд╣рд╛рдБ рд╕рд╡рд╛рд▓ рд╣реИ: "рдореИрдВ рдХреИрд╕реЗ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддрд╛ рд╣реВрдБ рдХрд┐ рдореАрдбрд┐рдпрд╛рдкреНрд▓реЗрдЗрдВрдЧ рдЕрдкрдбреЗрдЯ рдХреА рдЧрдИ рд╣реИ рдЬрдм рдСрдбрд┐рдпреЛрдкреНрд▓реЗрдЗрдВрдЧ рдЕрдкрдбреЗрдЯ рдХреА рдЧрдИ рд╣реЛ?"
рдЕрдорд╛рдиреНрдп рдЙрддреНрддрд░ : Ngrx / рдкреНрд░рднрд╛рд╡ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ!
@Effect() playMediaWithAudio$ = this.actions$.pipe( ofType('PLAY_AUDIO'), map(() => ({ type: 'PLAY_MEDIA' })), );
рд╕рд╣реА рдЙрддреНрддрд░ : рдпрджрд┐ mediaPlaying
рдХреА рд╕реНрдерд┐рддрд┐ рдХрд╛ рдЕрдиреБрдорд╛рди рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд░рд╛рдЬреНрдп рдХреЗ рдкреЗрдбрд╝ рдХреЗ рджреВрд╕рд░реЗ рд╣рд┐рд╕реНрд╕реЗ рджреНрд╡рд╛рд░рд╛ рд▓рдЧрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдПрдХ рд╕рдЪреНрдЪреА рд╕реНрдерд┐рддрд┐ рдирд╣реАрдВ рд╣реИред рдпрд╣ рдПрдХ рд╡реНрдпреБрддреНрдкрдиреНрди рдЕрд╡рд╕реНрдерд╛ рд╣реИред рдпрд╣ рдЪрдпрдирдХрд░реНрддрд╛ рдХрд╛ рд╣реИ, рд╕реНрдЯреЛрд░ рдХрд╛ рдирд╣реАрдВред
audioPlaying$ = this.store.select('audioPlaying'); videoPlaying$ = this.store.select('videoPlaying'); mediaPlaying$ = combineLatest(this.audioPlaying$, this.videoPlaying$).pipe( map(([audioPlaying, videoPlaying]) => audioPlaying || videoPlaying), );
рдЕрдм рд╣рдорд╛рд░реА рд╕реНрдерд┐рддрд┐ рд╕реНрд╡рдЪреНрдЫ рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рдмрдиреА рд░рд╣ рд╕рдХрддреА рд╣реИ, рдФрд░ рд╣рдо рдХрд┐рд╕реА рдЪреАрдЬ рдХреЗ рд▓рд┐рдП Ngrx / рдкреНрд░рднрд╛рд╡ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдХрд┐ рджреБрд╖реНрдкреНрд░рднрд╛рд╡ рдирд╣реАрдВ рд╣реИред
2. рд░рд┐рдбреНрдпреВрд╕рд░ рдХреЗ рд╕рд╛рде рдХреНрд░рд┐рдпрд╛ рдХрд░рдирд╛
рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рдЖрдкрдХреЗ рд░рд╛рдЬреНрдп рдХреЗ рдкреЗрдбрд╝ рдореЗрдВ рдпреЗ рдЧреБрдг рд╣реИрдВ:
export interface State { items: { [index: number]: Item }; favoriteItems: number[]; }
рддрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЖрдЗрдЯрдо рдХреЛ рд╣рдЯрд╛ рджреЗрддрд╛ рд╣реИред рдЬрдм рд╣рдЯрд╛рдП рдЧрдП рдЕрдиреБрд░реЛрдз рдХреЛ рд╡рд╛рдкрд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╣рдорд╛рд░реЗ рдЖрд╡реЗрджрди рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП DELETE_ITEM_SUCCESS
рдХрд╛рд░реНрд░рд╡рд╛рдИ рднреЗрдЬреА рдЬрд╛рддреА рд╣реИред items
рд░рд┐рдбреНрдпреВрд╕рд░ рдореЗрдВ, items
рдСрдмреНрдЬреЗрдХреНрдЯ рд╕реЗ рдПрдХ рд╡реНрдпрдХреНрддрд┐рдЧрдд Item
рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдпрд╣ рддрддреНрд╡ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдкрд╕рдВрджреАрджрд╛рдЗрдЯреЗрдо рд╕рд░рдгреА рдореЗрдВ рдерд╛, рддреЛ рдпрд╣ рдЬрд┐рд╕ рддрддреНрд╡ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИ рд╡рд╣ рдЕрдиреБрдкрд╕реНрдерд┐рдд рд╣реЛрдЧрд╛ред рддреЛ рд╕рд╡рд╛рд▓ рдпрд╣ рд╣реИ рдХрд┐, DELETE_ITEM_SUCCESS
рдХрд╛рд░реНрд░рд╡рд╛рдИ рднреЗрдЬрддреЗ рд╕рдордп рдореИрдВ рдпрд╣ рдХреИрд╕реЗ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ рдХрд┐ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЛ favoriteItems
DELETE_ITEM_SUCCESS
рд╕реЗ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ?
рдЕрдорд╛рдиреНрдп рдЙрддреНрддрд░ : Ngrx / рдкреНрд░рднрд╛рд╡ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ!
@Effect() removeFavoriteItemId$ = this.actions$.pipe( ofType('DELETE_ITEM_SUCCESS'), map(() => ({ type: 'REMOVE_FAVORITE_ITEM_ID' })), );
рдЗрд╕рд▓рд┐рдП, рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рджреЛ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдПрдХ рдХреЗ рдмрд╛рдж рдПрдХ рднреЗрдЬреА рдЬрд╛рдПрдВрдЧреА, рдФрд░ рджреЛ reducers рдПрдХ рдХреЗ рдмрд╛рдж рдПрдХ рдирдП рд░рд╛рдЬреНрдп рд▓реМрдЯрд╛рдПрдВрдЧреЗред
рд╕рд╣реА рдЙрддреНрддрд░ : DELETE_ITEM_SUCCESS
рдХреЛ items
DELETE_ITEM_SUCCESS
рдФрд░ favoriteItems
рджреЛрдиреЛрдВ DELETE_ITEM_SUCCESS
рджреНрд╡рд╛рд░рд╛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
export function favoriteItemsReducer(state = initialState, action: Action) { switch (action.type) { case 'REMOVE_FAVORITE_ITEM': case 'DELETE_ITEM_SUCCESS': const itemId = action.payload; return state.filter(id => id !== itemId); default: return state; } }
рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд╛ рд▓рдХреНрд╖реНрдп рдЕрд▓рдЧ рд╣реЛрдирд╛ рд╣реИ рдХрд┐ рд░рд╛рдЬреНрдп рдХреЛ рдХреИрд╕реЗ рдмрджрд▓рдирд╛ рдЪрд╛рд╣рд┐рдПред рдХреНрдпрд╛ рд╣реБрдЖ DELETE_ITEM_SUCCESS
ред Reducers рдХрд╛ рдХрд╛рд░реНрдп рд░рд╛рдЬреНрдп рдореЗрдВ рдПрдХ рд╕рдорд╛рди рдкрд░рд┐рд╡рд░реНрддрди рдХрд╛ рдХрд╛рд░рдг рд╣реИред
favoriteItems
рд╕реЗ рдПрдХ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЛ рд╣рдЯрд╛рдирд╛ Item
рдХреЛ рд╣рдЯрд╛рдиреЗ рдХрд╛ рдХреЛрдИ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯ рдирд╣реАрдВ рд╣реИред рдкреВрд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рд╣реИ рдФрд░ рдЗрд╕реЗ reducers рджреНрд╡рд╛рд░рд╛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред Ngrx / рдкреНрд░рднрд╛рд╡реЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
3. рдШрдЯрдХ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░реЗрдВ
рдЖрдкрдХреЗ рдШрдЯрдХ рдХреЛ рд╕реНрдЯреЛрд░ рд╕реЗ рдбреЗрдЯрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рдЗрд╕реЗ рд╕рд░реНрд╡рд░ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд╕рд╡рд╛рд▓ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдбреЗрдЯрд╛ рдХреЛ рд╕реНрдЯреЛрд░ рдореЗрдВ рдХреИрд╕реЗ рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдШрдЯрдХ рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХреЗ?
рджрд░реНрджрдирд╛рдХ рддрд░реАрдХрд╛ : Ngrx / рдкреНрд░рднрд╛рд╡ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ!
рдШрдЯрдХ рдореЗрдВ, рд╣рдо рдПрдХ рдХрд╛рд░реНрд░рд╡рд╛рдИ рднреЗрдЬрдХрд░ рдЕрдиреБрд░реЛрдз рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:
ngOnInit() { this.store.dispatch({ type: 'GET_USERS' }); }
рдкреНрд░рднрд╛рд╡ рд╡рд░реНрдЧ рдореЗрдВ, рд╣рдо GET_USERS
:
@Effect getUsers$ = this.actions$.pipe( ofType('GET_USERS'), withLatestFrom(this.userSelectors.needUsers$), filter(([action, needUsers]) => needUsers), switchMap(() => this.getUsers()), map(users => ({ type: 'RECEIVE_USERS', users })), );
рдЕрдм рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рддрдп рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдорд╛рд░реНрдЧ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдореЗрдВ рдмрд╣реБрдд рд▓рдВрдмрд╛ рд╕рдордп рд▓рдЧрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╡рд╣ рдПрдХ рд╕реЗ рджреВрд╕рд░реЗ рдореЗрдВ рд╕реНрд╡рд┐рдЪ рдХрд░реЗрдЧрд╛ред рдХреБрд╢рд▓ рд╣реЛрдиреЗ рдФрд░ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдбреЗрдЯрд╛ рд▓реЛрдб рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЗрд╕ рдЕрдиреБрд░реЛрдз рдХреЛ рд░рджреНрдж рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЬрдм рдШрдЯрдХ рдирд╖реНрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╣рдо рдХрд╛рд░реНрд░рд╡рд╛рдИ рднреЗрдЬрдХрд░ рдЕрдиреБрд░реЛрдз рд╕реЗ рд╕рджрд╕реНрдпрддрд╛ рд╕рдорд╛рдкреНрдд рдХрд░ рджреЗрдВрдЧреЗ:
ngOnDestroy() { this.store.dispatch({ type: 'CANCEL_GET_USERS' }); }
рдЕрдм рдкреНрд░рднрд╛рд╡ рд╡рд░реНрдЧ рдореЗрдВ рд╣рдо рджреЛрдиреЛрдВ рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рд╕реБрдирддреЗ рд╣реИрдВ:
@Effect getUsers$ = this.actions$.pipe( ofType('GET_USERS', 'CANCEL_GET_USERS'), withLatestFrom(this.userSelectors.needUsers$), filter(([action, needUsers]) => needUsers), map(([action, needUsers]) => action), switchMap( action => action.type === 'CANCEL_GET_USERS' ? of() : this.getUsers().pipe(map(users => ({ type: 'RECEIVE_USERS', users }))), ), );
рд╕рдм рдареАрдХ рд╣реИред рдЕрдм рдПрдХ рдФрд░ рдбреЗрд╡рд▓рдкрд░ рдПрдХ рдШрдЯрдХ рдЬреЛрдбрд╝рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЙрд╕реА HTTP рдЕрдиреБрд░реЛрдз рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ (рд╣рдо рдЕрдиреНрдп рдШрдЯрдХреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреЛрдИ рдзрд╛рд░рдгрд╛ рдирд╣реАрдВ рдмрдирд╛рдПрдВрдЧреЗ)ред рдШрдЯрдХ рдПрдХ рд╣реА рдХреНрд░рд┐рдпрд╛ рдХреЛ рдПрдХ рд╣реА рд╕реНрдерд╛рди рдкрд░ рднреЗрдЬрддрд╛ рд╣реИред рдпрджрд┐ рджреЛрдиреЛрдВ рдШрдЯрдХ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рд╕рдХреНрд░рд┐рдп рд╣реЛрддреЗ рд╣реИрдВ, рддреЛ рдкрд╣рд▓рд╛ рдШрдЯрдХ рдЗрд╕реЗ рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ HTTP рдЕрдиреБрд░реЛрдз рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИред рдЬрдм рджреВрд╕рд░рд╛ рдШрдЯрдХ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдХреБрдЫ рднреА рдЕрддрд┐рд░рд┐рдХреНрдд рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ needUsers
false
ред рдЕрджреНрднреБрдд!
рдлрд┐рд░, рдЬрдм рдкрд╣рд▓рд╛ рдШрдЯрдХ рдирд╖реНрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╡рд╣ CANCEL_GET_USERS
рднреЗрдЬ CANCEL_GET_USERS
ред рд▓реЗрдХрд┐рди рджреВрд╕рд░реЗ рдШрдЯрдХ рдХреЛ рдЕрднреА рднреА рдЗрд╕ рдбреЗрдЯрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╣рдо рдХрд┐рд╕реА рдЕрдиреБрд░реЛрдз рдХреЛ рд░рджреНрдж рд╣реЛрдиреЗ рд╕реЗ рдХреИрд╕реЗ рд░реЛрдХ рд╕рдХрддреЗ рд╣реИрдВ? рд╢рд╛рдпрдж рд╣рдо рд╕рднреА рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХрд╛ рдХрд╛рдЙрдВрдЯрд░ рд╢реБрд░реВ рдХрд░ рджреЗрдВрдЧреЗ? рдореИрдВ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдЗрд╕ рдмрд┐рдВрджреБ рдХреЛ рд╕рдордЭ рдЧрдП рд╣реИрдВред рд╣рдореЗрдВ рд╕рдВрджреЗрд╣ рд╣реЛрдиреЗ рд▓рдЧрд╛ рд╣реИ рдХрд┐ рдЗрди рдбреЗрдЯрд╛ рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдмреЗрд╣рддрд░ рддрд░реАрдХрд╛ рд╣реИред
рдЕрдм рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдПрдХ рдЕрдиреНрдп рдШрдЯрдХ рдкреНрд░рдХрдЯ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рдбреЗрдЯрд╛ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рддрдм рддрдХ рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рдЬрдм рддрдХ users
рдбреЗрдЯрд╛ рд╕реНрдЯреЛрд░ рдореЗрдВ рдкреНрд░рдХрдЯ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдпрд╣ рдЪреИрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡реЗрдм рд╕реЙрдХреЗрдЯ рдХрд╛ рдХрдиреЗрдХреНрд╢рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдХреБрдЫ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА, рдпрд╛ рдХреБрдЫ рдФрд░ред рд╣рдо рдирд╣реАрдВ рдЬрд╛рдирддреЗ рдХрд┐ users
рдХреЛ рджреЛ рдЕрдиреНрдп рдШрдЯрдХреЛрдВ рдХреА рд╕рджрд╕реНрдпрддрд╛ рд╕реЗ рдкрд╣рд▓реЗ рдпрд╛ рдмрд╛рдж рдореЗрдВ рдЗрд╕ рдШрдЯрдХ рдХреЛ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдпрд╛ рдирд╣реАрдВред
рдЗрд╕ рд╡рд┐рд╢реЗрд╖ рдкрд░рд┐рджреГрд╢реНрдп рдХреЗ рд▓рд┐рдП рдореБрдЭреЗ рдЬреЛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫреА рдорджрдж рдорд┐рд▓реА, рд╡рд╣ рд╣реИ рдпрд╣ рдмреЗрд╣рддрд░реАрди рдкреЛрд╕реНрдЯ ред рдЙрдирдХреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, callApiY
рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ callApiX
рдкрд╣рд▓реЗ рд╣реА рдкреВрд░рд╛ рдХрд░ рд▓рд┐рдпрд╛ рдЬрд╛рдПред рдореИрдВрдиреЗ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рддрд╛рдХрд┐ рдпрд╣ рдХрдо рдбрд░рд╛рдиреЗ рд╡рд╛рд▓рд╛ рд▓рдЧреЗ, рд▓реЗрдХрд┐рди рдЕрдзрд┐рдХ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рдореВрд▓ рдкреЛрд╕реНрдЯ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВ:
@Effect() actionX$ = this.actions$.pipe( ofType('ACTION_X'), map(toPayload), switchMap(payload => this.api.callApiX(payload).pipe( map(data => ({ type: 'ACTION_X_SUCCESS', payload: data })), catchError(err => of({ type: 'ACTION_X_FAIL', payload: err })), ), ), ); @Effect() actionY$ = this.actions$.pipe( ofType('ACTION_Y'), map(toPayload), withLatestFrom(this.store.select(state => state.someBoolean)), switchMap(([payload, someBoolean]) => { const callHttpY = v => { return this.api.callApiY(v).pipe( map(data => ({ type: 'ACTION_Y_SUCCESS', payload: data, })), catchError(err => of({ type: 'ACTION_Y_FAIL', payload: err, }), ), ); }; if (someBoolean) { return callHttpY(payload); } return of({ type: 'ACTION_X', payload }).merge( this.actions$.pipe( ofType('ACTION_X_SUCCESS', 'ACTION_X_FAIL'), first(), switchMap(action => { if (action.type === 'ACTION_X_FAIL') { return of({ type: 'ACTION_Y_FAIL', payload: 'Because ACTION_X failed.', }); } return callHttpY(payload); }), ), ); }), );
рдЕрдм рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЬреЛрдбрд╝реЗрдВ рдХрд┐ HTTP рдЕрдиреБрд░реЛрдз рд░рджреНрдж рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрдм рдШрдЯрдХреЛрдВ рдХреЛ рдЕрдм рдЙрдирдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдФрд░ рдпрд╣ рдФрд░ рднреА рдЬрдЯрд┐рд▓ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред
ред ред ред
рддреЛ, рдбреЗрдЯрд╛ рдирд┐рд░реНрднрд░рддрд╛ рдкреНрд░рдмрдВрдзрди рдХреЗ рд╕рд╛рде рдЗрддрдиреА рд╕рдорд╕реНрдпрд╛рдПрдВ рдХреНрдпреЛрдВ рд╣реИрдВ рдЬрдм RxJS рдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЖрд╕рд╛рди рдмрдирд╛рдирд╛ рдЪрд╛рд╣рд┐рдП?
рд╣рд╛рд▓рд╛рдБрдХрд┐ рд╕рд░реНрд╡рд░ рд╕реЗ рдЖрдиреЗ рд╡рд╛рд▓рд╛ рдбреЗрдЯрд╛ рддрдХрдиреАрдХреА рд░реВрдк рд╕реЗ рдПрдХ рд╕рд╛рдЗрдб рдЗрдлрд╝реЗрдХреНрдЯ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ Ngrx / рдЗрдлрд╝реЗрдХреНрдЯ рдЗрд╕реЗ рд╕рдВрднрд╛рд▓рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рд╣реИред
рдШрдЯрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдирдкреБрдЯ / рдЖрдЙрдЯрдкреБрдЯ рдЗрдВрдЯрд░рдлреЗрд╕ рд╣реИрдВред рд╡реЗ рдбреЗрдЯрд╛ рджрд┐рдЦрд╛рддреЗ рд╣реИрдВ рдФрд░ рдЙрд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдП рдЧрдП рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рднреЗрдЬрддреЗ рд╣реИрдВред рдЬрдм рдХреЛрдИ рдШрдЯрдХ рд▓реЛрдб рд╣реЛрддрд╛ рд╣реИ, рддреЛ рд╡рд╣ рдЗрд╕ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдХреА рдЧрдИ рдХреЛрдИ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдирд╣реАрдВ рднреЗрдЬрддрд╛ рд╣реИред рд╡рд╣ рдбреЗрдЯрд╛ рджрд┐рдЦрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИред рдпрд╣ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рд╕рджрд╕реНрдпрддрд╛ рдХреА рддрд░рд╣ рдЕрдзрд┐рдХ рд╣реИред
рдмрд╣реБрдд рдмрд╛рд░ рдЖрдк рдРрд╕реЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдбреЗрдЯрд╛ рдЕрдиреБрд░реЛрдз рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрд░рд┐рдпрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдпреЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯреНрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЕрд╡рд▓реЛрдХрди рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢реЗрд╖ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред рдФрд░, рдЬреИрд╕рд╛ рдХрд┐ рд╣рдордиреЗ рджреЗрдЦрд╛, рдпрд╣ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдмрд╣реБрдд рдЕрд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдФрд░ рдмреЛрдЭрд┐рд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╕реЗ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдм рдХрд░рдирд╛, рдЕрдкреНрд░рдорд╛рдгрд┐рдд рдХрд░рдирд╛ рдФрд░ рд╕реНрд╡рдпрдВ рдХреЛ рджреЗрдЦрдиреЗ рдпреЛрдЧреНрдп рдмрдирд╛рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИред
ред ред ред
рдХрдо рджрд░реНрджрдирд╛рдХ рддрд░реАрдХрд╛ : рдШрдЯрдХ рдЕрд╡рд▓реЛрдХрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЙрдиреНрд╣реЗрдВ рд╕рджрд╕реНрдпрддрд╛ рджреЗрдХрд░ рдбреЗрдЯрд╛ рдореЗрдВ рдЕрдкрдиреА рд░реБрдЪрд┐ рджрд░реНрдЬ рдХрд░реЗрдЧрд╛ред
рд╣рдо рд╡реЗ рдЕрд╡рд▓реЛрдХрди рдпреЛрдЧреНрдп рдмрдирд╛рдПрдВрдЧреЗ рдЬрд┐рдирдореЗрдВ рдЖрд╡рд╢реНрдпрдХ HTTP рдЕрдиреБрд░реЛрдз рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдкреНрд░рднрд╛рд╡ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рд╢реБрджреНрдз RxJS рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ-рджреВрд╕рд░реЗ рдкрд░ рдирд┐рд░реНрднрд░ рдХрдИ рд╕рджрд╕реНрдпрддрд╛рдПрдБ рдФрд░ рдХреНрд╡реЗрд░реА рд╢реНрд░реГрдВрдЦрд▓рд╛рдУрдВ рдХреЛ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░рдирд╛ рдХрд┐рддрдирд╛ рдЖрд╕рд╛рди рд╣реИред
рд╕реЗрд╡рд╛ рдореЗрдВ рдпреЗ рджреЗрдЦрдиреЗ рдпреЛрдЧреНрдп рдмрдирд╛рдПрдВ:
requireUsers$ = this.store.pipe( select(selectNeedUser), filter(needUsers => needUsers), tap(() => this.store.dispatch({ type: 'GET_USERS' })), switchMap(() => this.getUsers()), tap(users => this.store.dispatch({ type: 'RECEIVE_USERS', users })), finalize(() => this.store.dispatch({ type: 'CANCEL_GET_USERS' })), share(), ); users$ = muteFirst( this.requireUsers$.pipe(startWith(null)), this.store.pipe(select(selectUsers)), );
users$
рд╕рджрд╕реНрдпрддрд╛ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ requireUsers$
рдФрд░ this.store.pipe(select(selectUsers))
рджреЛрдиреЛрдВ рдХреЛ рдкреНрд░реЗрд╖рд┐рдд рдХреА рдЬрд╛рдПрдЧреА, рд▓реЗрдХрд┐рди рдбреЗрдЯрд╛ рдХреЗрд╡рд▓ рдЗрд╕ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ this.store.pipe(select(selectUsers))
( muteFirst
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди muteFirst
рдФрд░ рдлрд┐рдХреНрд╕реНрдб muteFirst
рдЙрд╕рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╕рд╛рдеред)
рдШрдЯрдХ рдореЗрдВ:
ngOnInit() { this.users$ = this.userService.users$; }
рдЪреВрдВрдХрд┐ рдпрд╣ рдбреЗрдЯрд╛ рдирд┐рд░реНрднрд░рддрд╛ рдЕрдм рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЕрд╡рд▓реЛрдХрди рдпреЛрдЧреНрдп рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо async
рдкрд╛рдЗрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рд╕рджрд╕реНрдпрддрд╛ рдФрд░ рд╕рджрд╕реНрдпрддрд╛ рд╕рдорд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рд╣рдореЗрдВ рдЕрдм рдХрд╛рд░реНрд░рд╡рд╛рдИ рднреЗрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдпрджрд┐ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рдЕрдВрддрд┐рдо рдШрдЯрдХ рдХрд╛ рдорд╛рд░реНрдЧ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИ, рддреЛ HTTP рдЕрдиреБрд░реЛрдз рд░рджреНрдж рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдпрд╛ рд╡реЗрдм рд╕реЙрдХреЗрдЯ рдмрдВрдж рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред
рдбреЗрдЯрд╛ рдирд┐рд░реНрднрд░рддрд╛ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
requireUsers$ = this.store.pipe( select(selectNeedUser), filter(needUsers => needUsers), tap(() => this.store.dispatch({ type: 'GET_USERS' })), switchMap(() => this.getUsers()), tap(users => this.store.dispatch({ type: 'RECEIVE_USERS', users })), share(), ); users$ = muteFirst( this.requireUsers$.pipe(startWith(null)), this.store.pipe(select(selectUsers)), ); requireUsersExtraData$ = this.users$.pipe( withLatestFrom(this.store.pipe(select(selectNeedUsersExtraData))), filter(([users, needData]) => Boolean(users.length) && needData), tap(() => this.store.dispatch({ type: 'GET_USERS_EXTRA_DATA' })), switchMap(() => this.getUsers()), tap(users => this.store.dispatch({ type: 'RECEIVE_USERS_EXTRA_DATA', users, }), ), share(), ); public usersExtraData$ = muteFirst( this.requireUsersExtraData$.pipe(startWith(null)), this.store.pipe(select(selectUsersExtraData)), );
рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЗ рд╕рд╛рде рдЙрдкрд░реЛрдХреНрдд рд╡рд┐рдзрд┐ рдХреА рд╕рдорд╛рдирд╛рдВрддрд░ рддреБрд▓рдирд╛ рдпрд╣рд╛рдВ рджреА рдЧрдИ рд╣реИ:

рд╢реБрджреНрдз рдЕрд╡рд▓реЛрдХрди рдпреЛрдЧреНрдп рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдХреА рдХрдо рд▓рд╛рдЗрдиреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдФрд░ рдпрд╣ рдкреВрд░реА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ рдбреЗрдЯрд╛ рдирд┐рд░реНрднрд░рддрд╛ рд╕реЗ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд╕рджрд╕реНрдпрддрд╛ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рддреА рд╣реИред (рдореИрдВрдиреЗ finalize
рдХрдердиреЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджрд┐рдпрд╛, рдЬреЛ рдореВрд▓ рд░реВрдк рд╕реЗ рддреБрд▓рдирд╛ рдХреЛ рдЕрдзрд┐рдХ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рд╢рд╛рдорд┐рд▓ рдХрд┐рдП рдЧрдП рдереЗ, рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЙрдирдХреЗ рдмрд┐рдирд╛, рдкреНрд░рд╢реНрди рдЕрднреА рднреА рддрджрдиреБрд╕рд╛рд░ рд╣реЛрдВрдЧреЗред)

рдирд┐рд╖реНрдХрд░реНрд╖
Ngrx / рдкреНрд░рднрд╛рд╡ рдПрдХ рдорд╣рд╛рди рдЙрдкрдХрд░рдг рд╣реИ! рд▓реЗрдХрд┐рди рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЗрди рд╕рд╡рд╛рд▓реЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:
- рдХреНрдпрд╛ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯ рд╣реИ?
- рдХреНрдпрд╛ Ngrx / рдкреНрд░рднрд╛рд╡ рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рд╣реИ?