import { Injectable } from '@angular/core'; import { MapOption } from './list.type' @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; } } } }