ListView上拉加载下拉刷新

  • A+
所属分类:Web前端
摘要

  

import { utils } from 'goblin'; import { ListView, Button, PullToRefresh } from 'antd-mobile'; import { NoDataPanel } from 'components'; import { connect } from 'dva'; import { encryptionEtcObuNumber, isNotEmptyStr } from 'utils/tool'; import { PAGE_SIZE } from 'configs/constants'; import { namespace } from '../model';  /**  * 自定义body的包裹组件  * 问题:为啥将render里面无数据逻辑移入此方法  * 原因:解决下拉刷新时,刷新提示一直显示的issue  */ function ListContainer(props) {   const dataList = props.dataList || [];    return (     <div className="am-list-body my-body">       {         dataList.length > 0 ? props.children : <NoDataPanel>           <p>             暂时没有任何数据           </p>         </NoDataPanel>       }     </div>   ); }  @connect(state => state[namespace], dispatch => ({   replaceObuOrder(data) {     return dispatch({ type: `${namespace}/replaceObuOrder`, payload: { ...data, pageSize: PAGE_SIZE } });   },   fetchUpdateState(data) {     return dispatch({ type: `${namespace}/fetchUpdateState`, payload: data });   }, }))  class ReplaceObuOrder extends React.Component {   constructor(props) {     super(props);     const dataSource = new ListView.DataSource({       rowHasChanged: (row1, row2) => row1 !== row2,     });      this.state = {       dataList: [],       dataSource,       useBodyScroll: true, // 使用html的body作为滚动容器       refreshing: true, // 是否显示刷新状态       isLoading: true, // 是否在加载中       hasMore: true, // 是否最后一页数据       preId: '', // 上一页最后一条记录Id     };   }    componentDidMount() {     utils.setTitle('订单列表');      // 修复当前页面有滚动条,从下页面回退到当前页面,ios出现白屏     if ('scrollRestoration' in window.history) {       window.history.scrollRestoration = 'manual'; // 改为manual之后,就不会记录滚动位置     }      const { replaceObuOrder } = this.props;     replaceObuOrder();   }    /**    * 描述:数据有变化时;或者数据未变化,但是state的dataList为空时,更新state    * 问题:(this.state.dataList.length < 1)为了防止多个页面共用一个model,       从其他页面进入多次进入该页面,由于数据未变化,出现数据不展示的情况    */   componentWillReceiveProps({ obuOrder }) {     const { dataSource } = this.state;      if ((JSON.stringify(obuOrder) !== JSON.stringify(this.props.obuOrder))     || (this.state.dataList.length < 1)) {       const num = obuOrder.length;       const newList = [...this.state.dataList, ...obuOrder];        // eslint-disable-next-line       this.setState({         dataList: newList,         preId: (num > 0) ? obuOrder[num - 1].id : '',         dataSource: dataSource.cloneWithRows(newList),         hasMore: obuOrder.length === PAGE_SIZE,         isLoading: false,       });     }   }    /**    * 下拉刷新   */   onRefresh = async () => {     const { isLoading } = this.state;     const { replaceObuOrder, fetchUpdateState } = this.props;      // 避免下拉时重复发送相同请求     if (isLoading) {       return;     }     // 重置state     this.setState({       refreshing: true,       isLoading: true,       dataList: [],       preId: '',       hasMore: true,     });     await fetchUpdateState({       obuOrder: [],     });     await replaceObuOrder();     this.setState({ refreshing: false, isLoading: false });   }    /**    * 上拉加载   */   onEndReached = async () => {     const { hasMore, preId, isLoading } = this.state;     const { replaceObuOrder } = this.props;      if (!hasMore || isLoading) {       // hasMore避免最后一页时,重复请求数据       // 避免上拉时重复发送相同请求       return;     }      this.setState({ isLoading: true });     await replaceObuOrder({ preId });     this.setState({ isLoading: false });   }    getRowData = (data) => {     // Number强制进行类型转换,避免后端返回类型不一致     const gray = (Number(data.statusOrder) === 4) ? 'gray' : '';      return (<div className="replaceObuOrder-item">       <div className="title">         <font>{data.typeDes}</font>         <span><font className={gray}>{data.statusOrderDesc}</font>{data.subStatusDesc}</span>       </div>       <div className="detail">         <div>{data.vanNumber}</div>         <p>{data.cardName}:{isNotEmptyStr(data.cardNo) && encryptionEtcObuNumber(data.cardNo)}</p>         {isNotEmptyStr(data.deviceId) && <p>电子标签号:{encryptionEtcObuNumber(data.deviceId)}</p>}         {isNotEmptyStr(data.description) && <p>{data.description}</p>}         {isNotEmptyStr(data.subDescription) && <p>{data.subDescription}</p>}       </div>       <div className="my-btn">         {data.buttons && data.buttons.map(item => (<Button           className="button"           onClick={this.handleButton(data, item.id)}         >           {item.name}         </Button>))}       </div>     </div>);   }    handleButton = (data, id) => async () => {     const { fetchUpdateState, history } = this.props;      await fetchUpdateState({       selectedObuOrderItem: data,     });     if (Number(id) === 1) {       history.push('detail?normalProcess=false');     } else if (Number(id) === 4) {       history.push('pay?normalProcess=false');     } else if (Number(id) === 13) {       history.push('receiveInfo?normalProcess=false');     }   }    render() {     const { dataSource, useBodyScroll, refreshing, dataList, isLoading } = this.state;      return (       <div className="replaceObuOrder">         <ListView           dataSource={dataSource}           renderRow={rowData => this.getRowData(rowData)}           pageSize={PAGE_SIZE}           renderBodyComponent={() => <ListContainer dataList={dataList} />}           pullToRefresh={<PullToRefresh             distanceToRefresh={60}             refreshing={refreshing}             onRefresh={this.onRefresh}           />}           onEndReached={this.onEndReached}           onEndReachedThreshold={50}           useBodyScroll={useBodyScroll}           renderFooter={             () => (               <div>                 {!isLoading && '已经没有更多数据了'}               </div>             )           }         />       </div>     );   } }  export default ReplaceObuOrder;