weex-nuke
Version:
基于 Rax 、Weex 的高性能组件体系 ~~
196 lines (184 loc) • 4.61 kB
JavaScript
/** @jsx createElement */
;
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;