import { Injectable } from '@angular/core'; import { MapOption } from './list.type' export interface LoadMoreOption{ perPage?:number remote? onInit? onUpdate? onFinish? } @Injectable() export class List { constructor() {} /** * 给列表添加all,get,add,remove等方法 * @param {Array} lists 一个列表数组 * @returns {Object} 返回一个列表对象 */ set = (lists:Array = [], perPage?:number) => { perPage = perPage || 10; return { //分页个数 perPage: perPage, //返回所有列表数据 all: ()=>{ return lists; }, //返回列表数量 count: ()=>{ return lists.length; }, //返回当前分页数据 getPageData: (pageNumber) => { return lists.slice(perPage * (pageNumber - 1), perPage * pageNumber); }, //返回全部分页数据 getPageDataAll: (pageNumber) => { return lists.slice(0, perPage * pageNumber); }, getOne: (id) => { return lists[id]; }, remove: (list) => { lists.splice(lists.indexOf(list), 1); }, add: (newLists) => { lists = lists.concat(newLists); // 追加数组到lists } }; } /** * 统一map处理列表数据 * @param data 列表数据 * @param handle 列表单个元素处理函数 * @param option 配置 * @returns {Array} */ map = (data, handle,option?:MapOption) => { const self = this; if(!Array.isArray(data)) data = [data];// 非数组封装为数组 const output = []; for (let i = 0, n = data.length; i < n; i++) { let res = handle(data[i],i); if(res) output.push(res); } if(option && option.scope && option.name) { if(option.load) { self.loadData(option.scope, output, option); }else{ if(option.hasChild){ option.scope[option.name][option.id] = output; }else{ option.scope[option.name] = output; } } } return output; } /* * 加载数据+下拉加载 * @param $scope // 待加载的作用域 * @param listName // 待加载的数组名 * @param data // 待加载的来源数据,可以是$list封装过的,也可以是未封装过的 * @param getRemoteData // 获取远程数据 * */ loadData = ($scope, data, option) => { console.log('set remote'); const { name, id, perPage, hasChild, remote} = option; //判断是否被$list封装,如果没有则封装 if(!data || !data.getPageData) data = this.set(data, perPage); // 获取首页 if(hasChild){ $scope[name][id] = data.getPageData(1); }else{ $scope[name] = data.getPageData(1); } let current = hasChild ? ($scope[name][id].length / data.perPage) : ($scope[name].length / data.perPage); let max = data.count() / data.perPage; let timer; $scope.canBeLoaded = max > current; // 此方法当加载loading时调用(滑屏到指定位置) $scope.loadMoreData = (infiniteScroll) => { console.log('infiniteScroll',infiniteScroll); if(current == max){ if(remote){ return remote(data).then((res) => { data.add(res); // 将新数据添加到data中 max = data.count() / data.perPage; // 重新计算max if(max > current){ return update(); }else{ return finishUpdate(); } }); }else{ return finishUpdate(); } }else{ // 设定加载间隔 return new Promise((resolve)=>{ timer = setTimeout(() => { resolve(update()); }, 360); }); } // 更新数据和当前页面标识 function update() { if(hasChild){ $scope[name][id] = data.getPageDataAll(current + 1); }else{ $scope[name] = data.getPageDataAll(current + 1); } infiniteScroll.complete(); // 关闭loading current = hasChild ? ($scope[name][id].length / data.perPage) : ($scope[name].length / data.perPage); return current; } // 结束下拉loading function finishUpdate() { $scope.canBeLoaded = false; clearTimeout(timer); return null; } } } /** * 加载数据+下拉加载(新) * @param $scope 待加载的作用域 * @param listName 待加载的数组名 * @param data 待加载的来源数据,可以是$list封装过的,也可以是未封装过的 * @param option 获取远程数据 */ loadMore = (data, option:LoadMoreOption = {}) => { //判断是否被$list封装,如果没有则封装 if(!data || !data.getPageData) data = this.set(data, option.perPage); var getRemoteData = option.remote; // 远程数据接口 var onInit = option.onInit; // 初始化回调 var onUpdate = option.onUpdate; // 更新回调 var onFinish = option.onFinish; // 结束回调 var pageData = data.getPageData(1); var current = pageData.length / data.perPage; var max = data.count() / data.perPage; var timer; var canBeLoaded = max > current; //加载函数 var loadMoreHandle = (infiniteScroll) => { if(current == max){ if(getRemoteData){ getRemoteData(data).then((res) => { data.add(res); // 将新数据添加到data中 max = data.count() / data.perPage; // 重新计算max if(max > current){ update(); }else{ finishUpdate(); } }); }else{ finishUpdate(); } }else{ // 设定加载间隔为0.5秒 timer = setTimeout(() => { update(); }, 360); } // 更新数据和当前页面标识 function update() { var pageData = data.getPageDataAll(current + 1); current = pageData.length / data.perPage; onUpdate(pageData); infiniteScroll.complete(); // 关闭loading return current; } function finishUpdate() { clearTimeout(timer); onFinish(); } }; // == 调用初始化方法时,将当前分页数据、是否可加载变量和加载回调与当前作用域进行绑定 onInit(pageData, canBeLoaded, loadMoreHandle); } }