滚动列表页面到一定程度的时候,如果还有需要加载的列表数据,可以请求这些数据。在 post_index_store.dart 里面,可以先添加两个数据。
用 @observable 标注一下,类型是 int ,名字是 nextPage,表示下一次要加载的页码。再定义一个数据,@observable ,类型是 int? 名字是 totalCount ,它的值就是列表项目总共的数量。
下面再定义两个计算属性,用 @computed 标注一下,类型是 int,名字是 totalPages ,这个总共的页数我们得计算一下,就是用项目的总数,除以每一页的项目数量。
可以判断一下 totalCount 是不是等于 null ,如果是的话,就让这个 totalPages 等于 0 ,不然的话它的值可以计算一下,totalCount! 除以每页的项目数量,这里就是 AppConfig.postsPerPage ,算出来的这个结果,可以调用一下 ceil() 这个方法。
再定义一个计算属性,类型是 bool,名字是 hasMore,它表示是否还有要加载的数据,返回的值可以判断一下 totalPages 减去 nextPage 看一下结果是不是大于等于 0,如果是这个 hasMore 就会返回 true 。
setPosts
下面这个 setPosts 动作可以改造一下,这里可以判断一下 nextPage 是不是等于 1,如果是的话,就让 posts 等于 ObservableList.of(data) ,如果不是,就让这个 posts,等于 ObservableList.of ,一个列表,里面先把 posts 原有的东西放进来,后面再把 data 里的项目放进来。
setNextPage
然后定义一个新的动作,用 @action 标注一下,名字是 setNextPage ,一个可选参数,类型是 int 名字叫 data,在动作里判断一下 data 是不是不等于 null ,如果是,就让 nextPage 等于 data,不是,就让 nextPage 等于它原来的值加上 1 的结果。
setTotalCount
再定义一个动作,名字是 setTotalCount,接收一个 String? 类型的 data 参数,动作里 判断一下 data 是不是不等于 null ,如果是,让 totalCount 等于 int.parse 处理一下这个 data。
getPosts
然后我们再改造一下这个 getPosts 方法,在这个 try 区块里面,声明一个 queryParameters,等于一个对象,里面添加一个 'sort' ,值是 sort。 下面再声明一个东西,名字是 queryString ,值可以用一下 Uri,提供一个 queryParameters,值是 queryParameters,访问一下 query,这样这个 queryString 就是一个地址查询符字符串。
下面这个 uri ,在这个地址里面可以先添加一个 page 查询符,值是 $nextPage,然后再加上 queryString 。
请求成功以后,执行 setTotalCount ,把总共的项目数量交给它,我们的服务端会把这个总数放在一个特定的头部里面,这里可以用一下 response.headers ,头部的名字是 x-total-count 。
下面再执行 setNextPage 修改一下,下一页要请求的页码。
构造方法
在构造方法里面添加两个参数,this.nextPage,默认值是 1 ,再添加一个 this.totalCount。
post_index.dart
打开 post_index.dart,在这个 onScroll 里面,判断一下 store.touchDown ,并且 store.hasMore,表示还有要加载的数据,并且 !store.loading,就是当前不是正在加载数据的状态。满足所有这些条件,我们就可以执行 store.getPosts() 加载新的列表数据了。
测试
重新启动一下应用,然后在模拟器上测试一下,向下滚动这个列表页面,到一定程度,如果还有要加载的数据就会加载新的列表数据,我们的应用使用这些新的数据组织应用的界面,把它们显示出来。
修改
最后我们还得再修改一个地方,在 post_index_store.dart 里面,找到 setSort,这个动作是修改排序数据用的,这里可以先把 nextPage 设置成 1 。
再测试一下,先在这个最近页面,向下滚动页面,让它加载新页面的内容,这时候 nextPage 的值就发生变化了。 按一下头部的大标题,回到页面顶部,然后按一下热门,它会执行 setSort 这个动作,这个动作会先把 nextPage 设置成 1,然后把 sort 设置成 most_comments,排序发生变化,就会重新加载内容列表数据。