관찰 가능한 각도 스토리지가 있는 Redux
24040 단어 angulartypescriptreduxjavascript
저는 최근에 대형 프로젝트를 완성했습니다. 이 프로젝트는 NgRx를 Angular의 상태 관리에 사용했습니다. 처음에 저는 거의 어찌할 바를 몰랐습니다.NgRx의 일반적인 문제 중 하나는 대량의 템플릿 파일이 필요하다는 것이다.확실히 NgRx에서 선택기, 동작, 감축기와 효과를 실현할 때 관심점의 분리를 유지하면 제어할 수 없다.noob에 대해 말하자면, NgRx가 어떻게 redux를 실현하는지 이해하는 것은 매우 어려울 수 있으며, 생성할 수 있는 모든 파일을 처리하는 것은 말할 것도 없다.경험이 풍부한 고급 엔지니어라도 이런 경험에 굴복할 것이다.
Redux는 이렇게 복잡할 필요가 없습니다.Redux의 목적은 단방향 데이터 흐름 모드를 사용하여 복잡한 응용 프로그램의 상태 관리를 간소화하는 것이다.유지 모드가 간단하고 장점이 있습니다.
RxJS 비헤이비어 테마
공교롭게도 NgRx는 Angular에서 redux 모드를 실현하는 유일한 방법이 아니다.RxJS에서는 관찰 대상이 있는 저장소를 만들 수 있도록 사용할 수 있는 도구가 있습니다.내가 말한 패턴은 관찰 가능한 저장소라고 불린다.관찰 가능한 저장소의 가장 간단한 표현식은 다음과 같다.
this._state$ = new BehaviorSubject(initialState);
RxJS에는 본질적으로 관찰 가능한 API가 제공되지만 상태도 유지됩니다.BehaviorSubject
초기 상태를 사용합니다.관찰 가능한 스토리지
만약 우리가 응용 프로그램에서 관찰 가능한 저장소를 만드는 능력을 추상화하고 싶다면, 그것은 이렇게 보일 수도 있다.
export interface AbstractState {
[key: string]: any;
}
export class Store {
private _state$: BehaviorSubject<AbstractState>;
public state$: Observable<AbstractState>;
constructor (initialState: AbstractState) {
this._state$ = new BehaviorSubject(initialState);
this.state$ = this._state$.asObservable() as Observable<AbstractState>;
}
get state(): AbstractState {
return this._state$.getValue();
}
setState (nextState: AbstractState): void {
this._state$.next(nextState);
}
}
이것이 바로 추상적으로 관찰할 수 있는 저장의 모든 내용이다!Store 클래스에는 BehaviorSubject라는 개인 속성이 있습니다.
BehaviorSubject
라는 속성이 공개되어 전체 응용 프로그램에서 사용할 수 있습니다.우리는 state$
를 호출하여 상태를 검색하거나 getState()
을 호출하여 상태를 변경할 수 있다.이렇게 함으로써 우리는 관찰 대상의 모든 특징을 보존했다. 역사, 오류 처리, 그리고 모든jazz를 포함한다.NgRx에 비하면 매우 간단합니다.구현 상태
그리고 만약 우리가 응용 프로그램에서 상태를 만들고 싶다면, 그것은 이렇게 보일 수도 있다.
export interface SomeModel {
name: string
}
export class LocalState {
someModel: SomeModel[] = [];
}
@Injectable()
export class LocalStore extends Store {
public state$: Observable<LocalState>;
constructor () {
super(new LocalState());
}
}
상술한 실현에 관한 몇 가지 설명.주의, 우리는 일부 국부 상태를 처리하기 위해 클래스를 성명한 다음에 setState
성명 state$
을 성명했다.이것은 우리가 사용하는 것을 확보하기 위해서이다LocalStore
.그리고 구조 함수에서 호출LocalState
하여 LocalState에 전송하여 정확한 상태 실례화AbstractState
를 사용합니다.어셈블리에서 상태 사용
이제 우리는 부분적인 상태가 생겼으니, 구성 요소에서 그것과 상호작용할 때가 되었다.
super
만 주입하면 구독 상태 변경이 필요 없습니다.
export class MyComponent {
constructor(public store: LocalStore) {}
}
어셈블리의 템플릿에서 현재 상태를 BehaviorSubject
파이프와 함께 사용할 수 있습니다.보기는 자동으로 이 방식으로 상태 블록에 구독하고 구독 취소를 처리합니다.<ul>
<li *ngFor="let item of (store.state$ | async).someModel as SomeModel">{{item.name}}</li>
</ul>
Angular에 관찰 가능한 저장소를 연결하는 것은 정말 쉽다!지금까지 우리는 상태의 개념만 가지고 있는데 이것은 Redux 모델의 일부분이다.만약 우리가 감축기와 조작을 실현하고 싶다면, 그것은 보기에 무엇처럼 보입니까?현재, 우리는 이미 우리 자신의 관찰 가능한 저장소를 실현했다!이제 너는 너에게서 가져간 나의 시간을 되찾을 수 있다.
redux는 상태만이 아니다.redux의 동작과 감속기 모드로 상태를 관리하고 싶지만, 이 사용자 정의 구현에서는요?
동작과 감속기
이것은 동작과 감축기를 실현하는 방법일 뿐, 보기에는 NgRx와 비슷하지만, 샘플 파일은 훨씬 적다.
우선, 동작을 정의하고 동작의 외관을 위한 인터페이스를 만드는 매거를 만듭니다.
export enum LocalActions {
ADD = '[SomeModel] Add',
REPLACE = '[SomeModel] Replace',
FETCH = '[SomeModel] Fetch'
}
export interface LocalAction {
type: string;
payload?: SomeModel[];
}
이제 LocalStore에 Reducer 방법을 추가하여 다른 작업을 처리할 수 있습니다.reducer(state: LocalState, action?: LocalAction) {
switch (action.type) {
case LocalActions.ADD:
return {
...state,
someModel: [...state.someModel, action.payload]
};
case LocalActions.REPLACE:
return {
...state,
someModel: action.payload
};
case LocalActions.FETCH:
this._fetch$ = this.service.fetchSomeModel().pipe(
map(res => this.actions.emit({ type: LocalActions.REPLACE,
payload: res }))
).subscribe();
}
FETCH 작업에 서비스 메서드가 호출되었음을 알 수 있습니까?관심사의 분리를 유지하기 위해서, 우리는 모든 API 요청을 자신의 서비스에 보류한 다음, 이를 LocalState 클래스에 주입할 수 있다.@Injectable()
export class LocalStore extends Store {
public state$: Observable<LocalState>;
private _fetch$: Subscription;
constructor (public service: LocalService) {
super(new LocalState());
}
}
Local Store가 상태가 변경될 때 Reducer를 자동으로 호출하기 위해서, 확장된 Store 클래스를 업데이트해야 합니다.여기에서, 우리는 상점의 동작에 구독을 추가할 것입니다. 상점에서 확장된 모든 종류에서 동작을 실행할 수 있도록 Event Emitter라고 설명합니다.@Injectable()
export class Store {
private _subscription$: Subscription;
private _state$: BehaviorSubject<AbstractState>;
public state$: Observable<AbstractState>;
public actions: EventEmitter<AbstractAction> = new EventEmitter();
constructor (initialState: AbstractState) {
this._state$ = new BehaviorSubject(initialState);
this.state$ = this._state$.asObservable() as Observable<AbstractState>;
this._subscription$ = from(this.actions).pipe(
map((a: AbstractAction) => this.reducer(this.state, a)),
map((s: AbstractState) => this.setState(s))
).subscribe();
}
...
reducer(state: AbstractState, action?: AbstractAction) {
return state;
}
현재, 우리 응용 프로그램의 어느 곳에서든지, 예를 들어 위에서 설명한 구성 요소에서, 우리는 백엔드 요청을 보내고 LocalStore
조작으로 상태를 채울 수 있습니다!this.store.actions.emit({ type: LocalActions.FETCH });
또 무슨 일이 일어났습니까?
여기서 시작해서 이 구체적인 행동에 무슨 일이 일어날지 봅시다.
ngOnInit
에서, 우리가 동작을 스케줄링하는 발사기는 Reducer를 호출하는 구독을 가지고 있다.this._subscription$ = from(this.actions).pipe(
map((a: AbstractAction) => this.reducer(this.state, a)),
reducer에서, 우리는 한 서비스에 http 요청을 보냈고, 응답이 있는 다른 작업을 성공적으로 보냈을 때.case LocalActions.FETCH:
this.service.fetchSomeModel().pipe(
map(res => this.actions.emit({ type: LocalActions.REPLACE,
payload: res }))
reducer에서 전송 async
작업은 덮어쓰기 상태입니다.case LocalActions.REPLACE:
return {
...state,
someModel: action.payload
};
EventEmitter on State에 대한 구독도 호출FETCH
을 통해 상태를 업데이트하기 때문에 보기에서 자동으로 상태에 대한 변경 사항을 얻을 수 있습니다.from(this.actions).pipe(
map((a: AbstractAction) => this.reducer(this.state, a)),
map((s: AbstractState) => this.setState(s))
).subscribe();
이것은 우리의 구성 요소에서 보기를 업데이트하기 위한 조작을 보내기만 하면 된다는 것을 의미한다.비동기 파이프는 우리의 처리 상태를 위한 구독입니다.<ul>
<li *ngFor="let item of (store.state$ | async).someModel as SomeModel">{{item.name}}</li>
</ul>
여기 있다!여기서 중요한 것은redux는 간단할 수도 있고 복잡할 수도 있다는 것이다.자신의 상태 인코딩 메커니즘으로 저장되는 것을 관찰할 수 있습니다. 상당히 복잡한 라이브러리에서 상태 관리의 배후 상황을 알 수 있습니다.NgRx에 비해 Redux는 최소한의 템플릿으로 Angular에서 실행할 수 있으며, 우리 응용 프로그램에서 여전히 관심사 분리를 제공합니다.내 말 믿지 마.
이 블로그 게시물과 동영상을 보고 상점을 관찰할 수 있는 더 많은 정보를 알아보세요.
Simplifying Front-End State Management with Observable Store 저자: Dan Wahlin.
State management in Angular with observable store services 저자: Jure Bajt.
View Facades + RxJS저자: 토마스 벨슨.
나는 토마스 벨슨의 게시물에서 이런 관찰할 수 있는 상점의 생각을 처음 접했다.몇 년 전, 나의 팀은 그의ng-conf에서의 강연에 근거하여 완전한 AngularJS 응용 프로그램을 설계했다. 나는 결과에 대해 매우 만족한다.몇 년 후, 내가 그의 게시물View Facades + RxJS을 읽었을 때, 나는 서비스 외관과 관찰 가능한 상점을 시험해 보았다.그 이후로 나는 다시는 돌아오지 않았다.안 돼, NgRx.
2019년 ngconf대회에서 Observable stores는 전 세계를 휩쓸었고 RxJS를 사용하여 응용 프로그램에 상태를 제공하는 데모가 여러 개 있었다.YouTube 동영상이 발표된 후에 나는 여기에 링크를 발표할 것이다.
Data Composition With RxJS는 Deborah Kurata에서 제안합니다.
Reference
이 문제에 관하여(관찰 가능한 각도 스토리지가 있는 Redux), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/steveblue/redux-with-observable-stores-in-angular-1b3b텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)