Angular和Redux:分派由一个用户交互触发的两个操作(一个同步,一个异步)是否正确?
关于Angular 4和ngrx store中实现的Redux应用程序中的操作流,我有一个一般性问题 基于一篇优秀的帖子: 有一个角度组件-它包含的容器组件行为。它引用了用于加载数据的服务 组件加载数据。一旦数据到达,就会有一个操作被发送到存储在服务页面中。 已订阅组件以存储以下项目: 组成部分: 以及服务:Angular和Redux:分派由一个用户交互触发的两个操作(一个同步,一个异步)是否正确?,angular,redux,ngrx,Angular,Redux,Ngrx,关于Angular 4和ngrx store中实现的Redux应用程序中的操作流,我有一个一般性问题 基于一篇优秀的帖子: 有一个角度组件-它包含的容器组件行为。它引用了用于加载数据的服务 组件加载数据。一旦数据到达,就会有一个操作被发送到存储在服务页面中。 已订阅组件以存储以下项目: 组成部分: 以及服务: @Injectable() export class RestClient { constructor(private http: HttpClient, private st
@Injectable()
export class RestClient {
constructor(private http: HttpClient, private store: Store) {}
public loadItems(pageInfo: PageInfo): void {
this.http.get('items', {params: {page: pageInfo.page, itemsPerPage: page.size}})
.map(payload => ({
type: 'PAGE_LOADED',
payload: payload
}))
.subscribe(action => this.store.dispatch(action));
}
}
该组件有一个子组件-分页表示组件不包含使用Angular@Output和EventEmitter更改其页面的行为或对其引导实现的存储的引用。父组件实现onPageChangedpageInfo函数,该函数接收子组件发出的页面更改事件
现在的问题或困惑是:
在页面更改时,必须将新值分派到存储,并加载新数据
在onPageChange功能中应该做什么:
onPageChanged(pageInfo: PageInfo) {
this.store.dispatch({action: 'PAGE_CHANGED', payload: pageInfo});
this.client.loadList(pageInfo); // load next page
}
分页已更改,因此将一个操作分派到存储区:PAGE\u已更改
使用PageInfo-当前页面a和页面大小
必须加载下一页:所以下一步是为下一页调用RestClient服务:this.client.loadListpageInfo;
这个调用反过来异步地分派一个新的操作,该操作将加载下一页。
总之,UI中的页面更改会发出两个动作:
-换页
-已加载页面
onPageChange action上调度了两个操作是否正确?
在某种意义上,这两者是否应该联系在一起:
store.select('pageInfo')
.subscribe(pageInfo => this.client.loadList(pageInfo));
或者有其他更好的解决方案吗?我的解决方案与bryan60建议的一样,使用ngrx效果库:
onPageChanged(pageInfo: PageInfo) {
this.store.dispatch({action: 'PAGE_CHANGED', payload: pageInfo});
}
onPageChange调度已更改的操作页面,该页面使用新的分页信息更新存储
注册了一个副作用,即在页面上加载一个新页面,并异步触发加载成功或加载错误:
Rest客户端不再分派操作:
@Injectable()
export class RestClient {
constructor(private http: HttpClient, private store: Store) {}
public loadItems(pageInfo: PageInfo): Observable {
return this.http.get('items', {params: {page: pageInfo.page, itemsPerPage: page.size}});
}
}
在app.module.ts中注册效果:
不,永远不要这样做。存储结果不应触发操作,这会破坏单向信息流。这会产生几乎不可能发现的bug,甚至可能在应用程序中导致非常奇怪的无限循环。如果你看了Redux在Facebook上的最初演示,他们会谈论像这样的事情正是Redux想要解决的。当你这样做的时候,你正在产生一种副作用,而这正是你不应该做的。首先,感谢您阅读了这么长的问题:我认为这是一个非常常见的场景:用户操作导致一个操作被分派到存储更新,并且必须加载新数据,这反过来导致存储更新。有没有一种没有ngrx效果的解决方法,一种通用的重排方法?为什么你不想使用?它适用于像您这样的常见情况。一旦我了解了如何正确使用它,我可能会使用它:我只是想知道ngrx效果背后是什么,如果在clean Redux架构中有类似的方法的话。如果有使用ngrx效果的解决方案,请将其作为答案发布;没有NGRX的方法是将它们视为两个完全分离的动作。页面被更改,这会导致两个不同的状态更改,它们自己的不同负载完全描述了单个状态更改。操作1立即产生所需的任何即时UI效果,例如显示加载图标或其他内容。然后,在检索到描述更新数据并关闭加载图标的状态更改所需的数据后,将调度action 2 async。ngrx/效果有助于使这些动作之间的桥梁更加清晰,事件顺序更加直观。
@Effect() changePage$ = this.actions$
.ofType(applications.CHANGE_PAGE)
.switchMap(action => this.client.loadItems(page, itemsPerPage)
.map(payload => (new applications.LoadSuccessAction(payload)))
// If request fails, dispatch failed action
.catch(error => Observable.of(new applications.LoadErrorAction(error)))
);
@Injectable()
export class RestClient {
constructor(private http: HttpClient, private store: Store) {}
public loadItems(pageInfo: PageInfo): Observable {
return this.http.get('items', {params: {page: pageInfo.page, itemsPerPage: page.size}});
}
}
@NgModule({
imports: [
...
EffectsModule.run(ApplicationEffects),
...