ngrx/효과 라이브러리의 목적은?
나는 이 도서관에 대한 유용한 정보나 그 목적이 무엇인지 찾지 못했다.ngrx/effects가 이 라이브러리를 이미 알고 있는 개발자들에게 설명하고 코딩 방법에 대한 큰 예를 제공하는 것 같다.
내 질문:
- 행동의 근원은 무엇인가?
- ngrx/효과 라이브러리의 목적은 무엇인가; ngrx/store만 사용하는 것의 단점은 무엇인가?
- 사용 권장 시점은?
- 각진 rc 5+를 지지하나?RC 5+에서는 어떻게 구성하나?
고마워!
주제가 너무 광범위하다.그것은 튜토리얼과 같을 것이다.어쨌든 한번 해 볼게.정상적인 경우, 당신은 액션, 환원기, 상점을 갖게 될 것이다.조치는 가게가 파견하고, 감량기는 가게가 구독한다.그러면 환원제가 작용하여 새로운 상태를 형성한다.예를 들어 모든 주가 프런트엔드에 있지만 실제 앱에서는 백엔드 DB나 MQ 등을 불러야 하는데 이런 통화는 부작용이 있다.이러한 효과를 공통의 장소로 고려하는 데 사용된 프레임워크.
데이터베이스에 사용자 레코드를 저장한다고 가정해 봅시다.action: Action = {type: SAVE_PERSON, payload: person}
. 일반적으로 구성 요소가 직접 전화를 걸지 않음this.store.dispatch( {type: SAVE_PERSON, payload: person} )
환원기가 HTTP 서비스를 호출하도록 하고 대신 호출할 것이다.this.personService.save(person).subscribe( res => this.store.dispatch({type: SAVE_PERSON_OK, payload: res.json}) )
실제 오류 처리를 추가할 때 구성 요소 논리가 더 복잡해질 것이다.이것을 피하기 위해서, 그냥 전화하는 것이 좋을 것이다.this.store.dispatch( {type: SAVE_PERSON, payload: person} )
당신의 구성 요소로부터.
그것이 효과 라이브러리를 위한 것이다.환원기 앞에서 JI 서블릿 필터와 같은 역할을 한다.ACTION type(필터가 자바 월드의 URL과 일치할 수 있음)과 일치한 다음 그것에 대해 작용하고, 마침내 다른 동작, 또는 어떤 동작이나 복수의 동작을 반환한다.그런 다음 감쇠기는 효과의 출력 작용에 반응한다.
이전 예제를 계속하려면 효과 라이브러리를 사용하십시오.
@Effects() savePerson$ = this.stateUpdates$.whenAction(SAVE_PERSON)
.map<Person>(toPayload)
.switchMap( person => this.personService.save(person) )
.map( res => {type: SAVE_PERSON_OK, payload: res.json} )
.catch( e => {type: SAVE_PERSON_ERR, payload: err} )
직조 논리는 모든 효과 및 환원기 클래스에 집중되어 있다.그것은 쉽게 더 복잡해질 수 있고, 동시에 이 디자인은 다른 부품들을 훨씬 더 단순하고 재사용 가능하게 만든다.
예를 들어 UI에 자동저장+수동저장 기능이 있는 경우 불필요한 저장을 피하기 위해 타이머로 UI 자동저장부위를 트리거할 수 있고 사용자 클릭으로 수동부위를 트리거할 수 있다.둘 다 SAVE_CLIENT 액션을 전송한다.가로채기 효과는 다음과 같을 수 있다.
@Effects() savePerson$ = this.stateUpdates$.whenAction(SAVE_PERSON)
.debounce(300).map<Person>(toPayload)
.distinctUntilChanged(...)
.switchMap( see above )
// at least 300 milliseconds and changed to make a save, otherwise no save
호출
...switchMap( person => this.personService.save(person) )
.map( res => {type: SAVE_PERSON_OK, payload: res.json} )
.catch( e => Observable.of( {type: SAVE_PERSON_ERR, payload: err}) )
오류가 있는 경우에만 한 번만 작동한다.어획물이 외류에서 시도하기 때문에 에러가 발생하여 하천은 죽는다.통화는 다음과 같아야 한다.
...switchMap( person => this.personService.save(person)
.map( res => {type: SAVE_PERSON_OK, payload: res.json} )
.catch( e => Observable.of( {type: SAVE_PERSON_ERR, payload: err}) ) )
또는 다른 방법: 모든 ServiceClass 서비스 방법을 서버 측에서 오류 코드, 오류 메시지 및 래핑된 응답 개체를 포함하는 ServiceResponse로 변경.
export class ServiceResult {
error: string;
data: any;
hasError(): boolean {
return error != undefined && error != null; }
static ok(data: any): ServiceResult {
let ret = new ServiceResult();
ret.data = data;
return ret;
}
static err(info: any): ServiceResult {
let ret = new ServiceResult();
ret.error = JSON.stringify(info);
return ret;
}
}
@Injectable()
export class PersonService {
constructor(private http: Http) {}
savePerson(p: Person): Observable<ServiceResult> {
return http.post(url, JSON.stringify(p)).map(ServiceResult.ok);
.catch( ServiceResult.err );
}
}
@Injectable()
export class PersonEffects {
constructor(
private update$: StateUpdates<AppState>,
private personActions: PersonActions,
private svc: PersonService
){
}
@Effects() savePerson$ = this.stateUpdates$.whenAction(PersonActions.SAVE_PERSON)
.map<Person>(toPayload)
.switchMap( person => this.personService.save(person) )
.map( res => {
if (res.hasError()) {
return personActions.saveErrAction(res.error);
} else {
return personActions.saveOkAction(res.data);
}
});
@Injectable()
export class PersonActions {
static SAVE_OK_ACTION = "Save OK";
saveOkAction(p: Person): Action {
return {type: PersonActions.SAVE_OK_ACTION,
payload: p};
}
... ...
}
이전 코멘트에 대한 한 가지 수정 사항: Effect-Class와 Reducer-Class, 만약 당신이 Effect-class와 Reducer-class가 모두 동일한 액션 타입에 반응한다면, Reducer-class가 먼저 반응하고 그 다음 Effect-class가 반응한다.예를 들면 다음과 같다.한 구성 요소에는 클릭 한 번으로 다음과 같은 버튼이 있다.this.store.dispatch(this.clientActions.effectChain(1));
어느 쪽이 처리할 것인가.effectChainReducer
그리고 나서ClientEffects.chainEffects$
페이로드를 1에서 2로 증가시킨다. 500ms가 다른 동작을 방출할 때까지 기다린다.this.clientActions.effectChain(2)
,에된 후.effectChainReducer
적재량=2로, 그 다음에ClientEffects.chainEffects$
2에서 3으로 증가하면 방출한다.this.clientActions.effectChain(3)
클, ,,,, 10보다 더 커지기 전까지는 ,,,,ClientEffects.chainEffects$
발산하다this.clientActions.endEffectChain()
을 통해 저장 상태를 1000으로 변경effectChainReducer
, 마침내 여기서 멈춘다.
export interface AppState {
... ...
chainLevel: number;
}
// In NgModule decorator
@NgModule({
imports: [...,
StoreModule.provideStore({
... ...
chainLevel: effectChainReducer
}, ...],
...
providers: [... runEffects(ClientEffects) ],
...
})
export class AppModule {}
export class ClientActions {
... ...
static EFFECT_CHAIN = "Chain Effect";
effectChain(idx: number): Action {
return {
type: ClientActions.EFFECT_CHAIN,
payload: idx
};
}
static END_EFFECT_CHAIN = "End Chain Effect";
endEffectChain(): Action {
return {
type: ClientActions.END_EFFECT_CHAIN,
};
}
static RESET_EFFECT_CHAIN = "Reset Chain Effect";
resetEffectChain(idx: number = 0): Action {
return {
type: ClientActions.RESET_EFFECT_CHAIN,
payload: idx
};
}
export class ClientEffects {
... ...
@Effect()
chainEffects$ = this.update$.whenAction(ClientActions.EFFECT_CHAIN)
.map<number>(toPayload)
.map(l => {
console.log(`effect chain are at level: ${l}`)
return l + 1;
})
.delay(500)
.map(l => {
if (l > 10) {
return this.clientActions.endEffectChain();
} else {
return this.clientActions.effectChain(l);
}
});
}
// client-reducer.ts file
export const effectChainReducer = (state: any = 0, {type, payload}) => {
switch (type) {
case ClientActions.EFFECT_CHAIN:
console.log("reducer chain are at level: " + payload);
return payload;
case ClientActions.RESET_EFFECT_CHAIN:
console.log("reset chain level to: " + payload);
return payload;
case ClientActions.END_EFFECT_CHAIN:
return 1000;
default:
return state;
}
}
위의 코드를 실행할 경우 출력은 다음과 같아야 한다.
클라이언트-저감기.ts:51 환원기 체인이 수준: 1
1client-reason.ts:72 효과 효과 인디아나: 1
클라이언트-저감기.ts:51 환원기 체인이 수준: 2
2client-reason.ts:72 효과 효과 인디아나: 2
클라이언트-저감기.ts:51 환원기 체인이 수준: 3
3client-result.ts:72 효과 인데 cannabled: 3
... ...
클라이언트-저감기.ts:51 환원기 체인이 수준: 10
10client-result.ts:72 효과 인데 수리가: 10
환원기가 효과 전에 먼저 작동한다는 것을 나타내며, Effect-Class는 사전 인터셉터가 아니라 사후 인터셉터다.흐름 다이어그램 참조:
참조URL: https://stackoverflow.com/questions/39552067/what-is-the-purpose-of-ngrx-effects-library
'Programing' 카테고리의 다른 글
대응: 위험하게 SetInner를 사용하여 삽입할 때 스크립트 태그가 작동하지 않음HTML (0) | 2022.03.10 |
---|---|
잘못된 URL 매개 변수를 사용하여 404 페이지로 리디렉션하는 방법 (0) | 2022.03.10 |
react-reason v4에서 서로 다른 경로 경로에 동일한 구성 요소 사용 (0) | 2022.03.09 |
페이지 다시 로드에서 매개 변수가 작동하지 않는 vue-properties 경로 (0) | 2022.03.09 |
Vuejs v-select에서 개체의 속성에 액세스하는 방법 (0) | 2022.03.09 |