这地方有个坑,dio必须结合json序列号和反序列的库一起用,不然Dio无法将数据源解析成Response类型
Effect<ListState> buildEffect() { return combineEffects(<Object, Effect<ListState>>{ ///进入页面就执行的初始化操作 Lifecycle.initState: _init, }); } void _init(Action action, Context<ListState> ctx) async { String apiUrl = "http://www.wanandroid.com/project/list/1/json"; Response response = await Dio().get(apiUrl); ItemDetailBean itemDetailBean = ItemDetailBean.fromJson(json.decode(response.toString())); List<Datas> itemDetails = itemDetailBean.data.datas; ///构建符合要求的列表数据源 List<ItemState> items = List.generate(itemDetails.length, (index) { return ItemState(itemDetail: itemDetails[index]); }); ///通知更新列表数据源 ctx.dispatch(ListActionCreator.updateItem(items)); }reducer
最后就是更新操作了哈,这里就是常规写法了
Reducer<ListState> buildReducer() { return asReducer( <Object, Reducer<ListState>>{ ListAction.updateItem: _updateItem, }, ); } ListState _updateItem(ListState state, Action action) { return state.clone()..items = action.payload; } 列表修改-单item刷新 效果图这次来演示列表的单item更新,没有网络请求的操作,所以代码逻辑就相当简单了
结构来看看代码结构
这地方很明显得发现,list_edit主体文件很少,因为这边直接在state里初始化了数据源,就没有后期更新数据的操作,所以就不需要:action,effect,reducer这三个文件!item模块则直接在reducer里更新数据,不涉及相关复杂的逻辑,所以不需要:effect文件。
列表模块
这次列表模块是非常的简单,基本不涉及什么流程,就是最基本初始化的一个过程,将state里初始化的数据在view中展示
state ---> view
state
老规矩,先来看看state中的代码
这里一些新建了变量,泛型是ItemState(item的State),items变量初始化了一组数据;然后,同样继承了MutableSource,实现其相关方法
class ListEditState extends MutableSource implements Cloneable<ListEditState> { List<ItemState> items; @override ListEditState clone() { return ListEditState()..items = items; } @override Object getItemData(int index) => items[index]; @override String getItemType(int index) => ListItemAdapter.itemName; @override int get itemCount => items.length; @override void setItemData(int index, Object data) { items[index] = data; } } ListEditState initState(Map<String, dynamic> args) { return ListEditState() ..items = [ ItemState(id: 1, title: "列表Item-1", itemStatus: false), ItemState(id: 2, title: "列表Item-2", itemStatus: false), ItemState(id: 3, title: "列表Item-3", itemStatus: false), ItemState(id: 4, title: "列表Item-4", itemStatus: false), ItemState(id: 5, title: "列表Item-5", itemStatus: false), ItemState(id: 6, title: "列表Item-6", itemStatus: false), ]; }view
view的代码主体仅仅是个ListView.builder,没有什么额外Widget
Widget buildView(ListEditState state, Dispatch dispatch, ViewService viewService) { return Scaffold( appBar: AppBar( title: Text("ListEditPage"), ), body: ListView.builder( itemBuilder: viewService.buildAdapter().itemBuilder, itemCount: viewService.buildAdapter().itemCount, ), ); }adapter
和上面类型,adapter继承SourceFlowAdapter适配器
class ListItemAdapter extends SourceFlowAdapter<ListEditState> { static const String itemName = "item"; ListItemAdapter() : super( pool: <String, Component<Object>>{itemName: ItemComponent()}, ); }page
在page里面绑定adapter
class ListEditPage extends Page<ListEditState, Map<String, dynamic>> { ListEditPage() : super( initState: initState, view: buildView, dependencies: Dependencies<ListEditState>( ///绑定适配器 adapter: NoneConn<ListEditState>() + ListItemAdapter(), slots: <String, Dependent<ListEditState>>{}), middleware: <Middleware<ListEditState>>[], ); } item模块接下就是比较重要的item模块了,item模块的流程,也是非常的清晰
view ---> action ---> reducer
state
老规矩,先来看看state里面的代码;此处就是写常规变量的定义,这些在view中都能用得着
class ItemState implements Cloneable<ItemState> { int id; String title; bool itemStatus; ItemState({this.id, this.title, this.itemStatus}); @override ItemState clone() { return ItemState() ..title = title ..itemStatus = itemStatus ..id = id; } } ItemState initState(Map<String, dynamic> args) { return ItemState(); }view