NgRx 效果只执行一次
NgRx effect executed only once
我有一个模态 window 单击,当 Add user
按钮被单击时,它会在 textbox
中添加值,之后它会进行一些内部调用,例如检查textbox
中的值。 http
调用在效果中执行,仅在第一个条目时被调用。
问题是做后端调用的effect只执行了一次
模态模板:
<button class="close" mat-button (click)="closeDialog()">x</button>
<h1 mat-dialog-title>Share with other users</h1>
<div mat-dialog-content>
<ng-container *ngFor="let principal of data.productList.sharedWith; trackBy: sharedPrincipalsTrackFunction">
<p>{{principal.uid}} <button (click)="removeUserFromSharedProductList(data.productList.name, principal.uid)">x</button></p>
</ng-container>
<mat-form-field>
<mat-label>Share with other users</mat-label>
<input matInput [(ngModel)]="data.userId">
</mat-form-field>
</div>
<div mat-dialog-actions>
<button class="btn btn-primary" mat-button (click)="addUserToProductList(data.productList.name, data.userId)" [disabled]="!data.userId">Add user</button>
</div>
组件的Typescript代码:
addUserToProductList(productListName: string, userId: string) {
this.productListService.shareProductList(productListName, userId);
this.updateDialogData(userId);
}
productListService.shareProductList
:
shareProductList(productListName: string, userId: string) {
this._store.dispatch(
ProductListActions.shareProductListWithUser({
productListName: productListName,
userId: userId
})
);
}
效果:
shareProductListWithUser$ = createEffect(() =>
this._actions$.pipe(
ofType(ProductListActions.shareProductListWithUser),
mergeMap(action =>
forkJoin(
of(action.productListName),
this._productListOccService.shareProductListWithUser(
action.productListName,
action.userId
)
)
),
switchMap(([productListName, response]) => [
ProductListActions.getMyProductLists(),
ProductListActions.shareProductListWithUserSuccess({
productListName: productListName,
principalList: response
})
]),
catchError((error) => {
console.log('Acelasi handler de kkt');
return EMPTY;
}))})
)
);
模块文件:
@NgModule({
declarations: [],
imports: [
CommonModule,
StoreModule.forFeature("productListState", productListReducer),
EffectsModule.forFeature([ProductListEffects])
],
providers: [ProductListOccService],
entryComponents: []
})
export class PrtListStoreModule {}
我调试了这个,但是我不明白为什么只调用一次效果。
问题出在catchError
,需要在其后添加repeat
才能再次启用效果
catchError((error) => { // <- closes the stream
console.log('Acelasi handler de kkt');
return EMPTY;
}))}),
repeat(), // <- resubscribes
理想情况下将 catchError
放在 .shareProductListWithUser
的 .pipe
中是正确的,然后你可以避免 repeat
,但是因为你对响应有依赖性,你可以保持代码原样并使用 repeat
.
实现所需的行为
我有一个模态 window 单击,当 Add user
按钮被单击时,它会在 textbox
中添加值,之后它会进行一些内部调用,例如检查textbox
中的值。 http
调用在效果中执行,仅在第一个条目时被调用。
问题是做后端调用的effect只执行了一次
模态模板:
<button class="close" mat-button (click)="closeDialog()">x</button>
<h1 mat-dialog-title>Share with other users</h1>
<div mat-dialog-content>
<ng-container *ngFor="let principal of data.productList.sharedWith; trackBy: sharedPrincipalsTrackFunction">
<p>{{principal.uid}} <button (click)="removeUserFromSharedProductList(data.productList.name, principal.uid)">x</button></p>
</ng-container>
<mat-form-field>
<mat-label>Share with other users</mat-label>
<input matInput [(ngModel)]="data.userId">
</mat-form-field>
</div>
<div mat-dialog-actions>
<button class="btn btn-primary" mat-button (click)="addUserToProductList(data.productList.name, data.userId)" [disabled]="!data.userId">Add user</button>
</div>
组件的Typescript代码:
addUserToProductList(productListName: string, userId: string) {
this.productListService.shareProductList(productListName, userId);
this.updateDialogData(userId);
}
productListService.shareProductList
:
shareProductList(productListName: string, userId: string) {
this._store.dispatch(
ProductListActions.shareProductListWithUser({
productListName: productListName,
userId: userId
})
);
}
效果:
shareProductListWithUser$ = createEffect(() =>
this._actions$.pipe(
ofType(ProductListActions.shareProductListWithUser),
mergeMap(action =>
forkJoin(
of(action.productListName),
this._productListOccService.shareProductListWithUser(
action.productListName,
action.userId
)
)
),
switchMap(([productListName, response]) => [
ProductListActions.getMyProductLists(),
ProductListActions.shareProductListWithUserSuccess({
productListName: productListName,
principalList: response
})
]),
catchError((error) => {
console.log('Acelasi handler de kkt');
return EMPTY;
}))})
)
);
模块文件:
@NgModule({
declarations: [],
imports: [
CommonModule,
StoreModule.forFeature("productListState", productListReducer),
EffectsModule.forFeature([ProductListEffects])
],
providers: [ProductListOccService],
entryComponents: []
})
export class PrtListStoreModule {}
我调试了这个,但是我不明白为什么只调用一次效果。
问题出在catchError
,需要在其后添加repeat
才能再次启用效果
catchError((error) => { // <- closes the stream
console.log('Acelasi handler de kkt');
return EMPTY;
}))}),
repeat(), // <- resubscribes
理想情况下将 catchError
放在 .shareProductListWithUser
的 .pipe
中是正确的,然后你可以避免 repeat
,但是因为你对响应有依赖性,你可以保持代码原样并使用 repeat
.