UNPKG

weex-nuke

Version:

基于 Rax 、Weex 的高性能组件体系 ~~

196 lines (184 loc) 4.61 kB
/** @jsx createElement */ 'use strict'; import { createElement, Component, findDOMNode, PropTypes, cloneElement, } from 'rax'; import { isWeex } from 'nuke-env'; import ScrollView from 'nuke-scroll-view'; import RefreshControl from 'nuke-refresh-control'; import Cell from 'nuke-cell'; import Header from 'nuke-header'; /** * ListView * @description 列表 */ class ListView extends Component { getChildContext() { return { isInARecyclerView: true, }; } resetLoadmore = () => { this.refs.list.resetLoadmore && this.refs.list.resetLoadmore(); }; scrollTo = (options) => { const x = parseInt(options.x); const y = parseInt(options.y); if (isWeex) { const dom = require('@weex-module/dom'); const firstCell = this.hasHeader ? findDOMNode(this.refs.cell1) : findDOMNode(this.refs.cell0); dom.scrollToElement(firstCell.ref, { offset: x || y || 0, }); } else { this.refs.list.scrollTo(options); } }; getChidren() { const { children, renderHeader, renderFooter, renderRow, dataSource = [], } = this.props; if (children) { return !Array.isArray(children) ? [children] : children; } const header = typeof renderHeader === 'function' ? renderHeader() : null; const footer = typeof renderFooter === 'function' ? renderFooter() : null; const body = dataSource.map((i, index) => renderRow(i, index)); return [].concat(header, body, footer); } render() { const { onEndReached, onEndReachedThreshold, id, style, showScrollbar, _keepScrollPosition, _autoWrapCell, renderRow, dataSource, renderHeader, renderFooter, ...others } = this.props; const children = this.getChidren(); const cells = children.map((child, index) => { const ref = `cell${index}`; if (child && child.type === RefreshControl) { this.hasHeader = true; } if (child) { if (_autoWrapCell && child.type != RefreshControl) { if (child.key) { return ( <Cell keepScrollPosition={_keepScrollPosition} ref={ref} key={child.key} > {child} </Cell> ); } return <Cell ref={ref}>{child}</Cell>; } return cloneElement(child, { ref }); } return <Cell ref={ref} />; }); if (isWeex) { return ( <list id={id} ref="list" style={style} onLoadmore={onEndReached} loadmoreretry loadmoreoffset={onEndReachedThreshold} showScrollbar={showScrollbar} {...others} > {cells} </list> ); } return ( <ScrollView id={id} style={style} onEndReached={onEndReached} onEndReachedThreshold={onEndReachedThreshold} showScrollbar={showScrollbar} {...others} > {cells} </ScrollView> ); } } ListView.childContextTypes = { isInARecyclerView: PropTypes.bool, }; ListView.propTypes = { /** * 列表底部加载更多的回调函数 onEndReached callback function */ onEndReached: PropTypes.func, /** * 列表到底部触发加载更多的位移量 offset of onEndReached been triggered */ onEndReachedThreshold: PropTypes.num, id: PropTypes.string, /** * 列表外层容器样式 style of list */ style: PropTypes.any, /** * 是否显示滚动条 show scrollbar or not when scrolling */ showScrollbar: PropTypes.boolean, /** * 是否保持上一次滚动位置 keep last scroll position */ _keepScrollPosition: PropTypes.boolean, /** * 是否自动包裹 cell 标签,仅用于非数据源模式 wrap cell tag or not */ _autoWrapCell: PropTypes.boolean, /** * 渲染数据的回调函数 render list row function */ renderRow: PropTypes.func, /** * 数据源 data souce of the list */ dataSource: PropTypes.array, /** * 渲染头部的回调函数 render list header function */ renderHeader: PropTypes.func, /** * 渲染尾的回调函数 render list footer function */ renderFooter: PropTypes.func, }; ListView.defaultProps = { onEndReachedThreshold: 500, _keepScrollPosition: false, _autoWrapCell: true, showScrollbar: false, }; ListView.RefreshControl = RefreshControl; ListView.Cell = Cell; ListView.Header = Header; export default ListView;