在我的 razor 组件中,我使用了一个Virtualize
组件(此处的文档),ItemsProviderDelegate
该组件被实现为一种async
从 API 批量加载数据传输对象 (DTO) 的方法。该方法看起来像这样:
private async ValueTask<ItemsProviderResult<Dto>> LoadDtosAsync(ItemsProviderRequest request)
{
// Massage parameters and dispatch action
// _stateFacade is essentially a wrapper around
// Dispatcher.Dispatch(new LoadDtosAction())
_stateFacade.LoadDtos(request.StartIndex, request.Count);
// I make the assumption here that 'IsLoading' is immediately
// 'true' after the LoadDtosAction is dispatched. I think
// that this is probably a bad assumption because
// Dispatcher.Dispatch() is probably not synchronous
// under-the-hood.
// dtoState is an IState<Dto>
while(_dtoState.Value.IsLoading)
{
// My current 'solution' to wait for the data to be loaded.
await Task.Delay(100);
}
// Provide the items to the Virtualize component for rendering...
return new ItemsProviderResult<Dto>(
_dtoState.Value.VirtualizedDtos ?? new List<Dto>(),
_dtoState.Value.DtosServerCount ?? 0
);
}
这已被证明是一种有效的方法来渲染来自后端模型集合的批量数据,这些数据可能非常大,同时保持请求大小很小。客户端应用程序一次只需要从 API 请求少量对象,而 UI 不需要愚蠢的“页面”控件,因为用户可以直观地滚动浏览显示数据的组件。
Fluxor 用于管理客户端应用程序的状态,包括组件已请求的当前 DTO Virtualize
。这抽象了从 API 请求批量 DTO 的逻辑,并允许根据哪个组件调度操作来触发副作用。
应用程序中的许多Action
类型都有一个object? Sender
属性,其中包含对调度操作的组件的引用。当组件中发送所需操作的原始方法不需要从操作返回的结果状态时,此方法有效。然后效果可以根据发送动作的组件的类型调用回调方法,例如:
public class UpdateDtoEffect : Effect<UpdateDtoSuccessAction>
{
protected override async Task HandleAsync(UpdateDtoSuccessAction action, IDispatcher dispatcher)
{
var updateDtoForm = action.Sender as UpdateDtoForm;
if (updateDtoForm is not null)
{
await updateDtoForm.OnSuccessfulUpdate.InvokeAsync();
}
}
}
当OnSuccessfulUpdate
被上述效果调用时,此操作的减速器将更新状态,因此回调方法可以依赖最新的状态信息。
AnItemsProviderDelegate
对这种方法提出了一个有趣的例外。为了正确实现委托,我们需要返回项目列表和服务器上可用项目的数量。LoadDtosAction
此信息存储在此功能的状态中,当成功时由减速器更新。在当前的实现中(上面一般表示),该LoadDtosAsync
方法做了两个我不喜欢的假设:
状态值在被分派
isLoading
时立即设置为 true 。LoadDtosAction
我不认为这总是正确的,因此组件有时会立即询问状态值以更新自身(这将导致显示先前的状态而不是结果状态)。生成的 action-reducer-effect 链最终会将状态
isLoading
值更新为false
。
是否有一种方法可以让ItemsProviderDelegate
实现分派LoadDtosAction
并“等待”操作的结果以返回ItemsProviderResult
?
- 编辑 - 动作流程如下所示:
LoadDtosAction =>
LoadDtosActionReducer (new state, 'isLoading':true) =>
LoadDtosActionEffect (performs asynchronous API call) =>
LoadDtosSuccessAction =>
LoadDtosSuccessActionReducer (new state, 'VirtualizedDtos':{IEnumerable<Dto>}, 'DtosServerCount':{int})
LoadDtosSuccessEffect (perform optional asynchronous callbacks to 'Sender')