最近碰到一个需求:页面有若干card,需要初始化请求数据,同时,该页面

1.点击card组件有页面跳转和页面刷新数据的需求

2.页面具有搜索栏,可以对card的标题进行搜索

分析:

【初始化请求数据】使用FutureBuilder组件即可完成需求,在future中定义请求数据函数即可,通过返回的snapshot组成返回的Widget刷新页面。

【搜索栏】通过获取的搜索数据对card的标题进行字符串匹配,筛选出符合条件的card后,通过更新返回的Widget来完成页面的刷新。

问题:

每当点击card的时候,再次返回本页面,因为FutureBuilder组件内置了setState函数,都会出发future请求从而对页面进行一次刷新,如果没有搜索栏功能,这刚好满足刷新页面的需求,可以不做处理。

但是,当存在搜索栏,在完成card的筛选后,使用setState函数必然重新触发future请求,请求到所有的数据会对进行筛选的card进行覆盖,这样就无法实现搜索功能。

解决:

尝试使用AsyncMemoizer类,对请求进行管理。(FutureBuilder多次请求的原理是每次setState函数刷新,都会返回一个新的对象,如果可以对对象进行保存,就可以避免重复刷新)

AsyncMemoizer类存在runOnce方法,可以实现避免重复刷新的需求。

但是在使用runOnce方法后,需求一又无法满足了。

此时可以通过

Future initUnreadList(bool flag) async{

  if(flag) {

    return await msgGetNoticeList(Api.noticeUnreadList,Token: Api.token);
  }
  else {
    return _memoizer.runOnce(() async {
      return await msgGetNoticeList(Api.noticeUnreadList,Token: Api.token);
    });
  }
}

这种添加flag的方式进行解决。

在后续的尝试中发现,我们不能阻止future请求的调用,只能通过flag来判断是否对snapshot.data中回传的数据更新到Widget中,通过这种方式实现对是否刷新的自主控制。

反思:

这种编程方式过于的不优雅,flag编程是程序员的大忌,但是暂时没有想到更好的替代方法。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐