/// import * as React from 'react'; import classNames from 'classnames'; import Hammer from 'react-hammerjs'; import assign from 'object-assign'; import WebApi from '../ajax/webapi'; const prefix = 'component-View'; class View extends React.Component { constructor(props: TspComponentViewProps, state: TspComponentViewState) { super(props, state); this.success = this.success.bind(this); this.timeoutCallback = this.timeoutCallback.bind(this); this.request = this.request.bind(this); } public static defaultProps: TspComponentViewProps = { delay: 0, loadingView: null, render: null, failView: null, timeoutView: null, emptyView: null, apiConfig: undefined, dataKey: 'result' }; public state: TspComponentViewState = { status: this.props.apiConfig ? undefined : (this.props.status ? this.props.status : 'complete'), updateId: 0 }; private data: any; /** * 接口请求是否完成 */ private loadingOver: boolean = false; /** * setTimeout的返回对象 */ // tslint:disable-next-line:typedef private timeoutInstance; public componentDidMount(): void { if (this.props.apiConfig) { if (this.props.delay) { this.timeoutInstance = setTimeout(() => { this.request(); }, this.props.delay); } else { this.request(); } } } public shouldComponentUpdate(nextProps: TspComponentViewProps, nextState: TspComponentViewState): boolean { const statusChange = (nextProps.status !== this.props.status) || (this.state.status !== nextState.status); const propsReloadIdChange = this.props.reloadId === undefined ? true : (nextProps.reloadId !== this.props.reloadId); const stateUpdateIdChange = this.state.updateId !== nextState.updateId; const propsRefreshIdChange = nextProps.refreshId !== this.props.refreshId; return statusChange || propsReloadIdChange || stateUpdateIdChange || propsRefreshIdChange; } public componentWillReceiveProps(nextProps: TspComponentViewProps): void { // 重载 if (nextProps.status !== this.props.status) { this.setState({ status: nextProps.status }); } if ((nextProps.reloadId !== this.props.reloadId) && this.props.apiConfig) { this.request(nextProps); } if (nextProps.refreshId !== this.props.refreshId) { this.setState({ updateId: this.state.updateId + 1 }); } } public componentWillUnmount(): void { clearTimeout(this.timeoutInstance); } /** * 根据状态渲染视图 */ public statusRender(): JSX.Element { switch (this.state.status) { case 'loading': return this.props.loadingView; case 'complete': return this.props.render(this.data); // case 'fail': return this.props.failView; case 'fail': return this.timeoutView(); case 'timeout': return this.timeoutView(); case 'empty': return this.props.emptyView; default: return null; } } /** * 超时视图,点击可刷新 */ public timeoutView(): JSX.Element { return ( this.request()}> {this.props.timeoutView} ); } /** * 发起请求 */ public request(props: TspComponentViewProps = this.props): void { const params = assign({}, props.apiConfig, { success: this.success, timeoutCallback: this.timeoutCallback, }); this.loadingOver = false; this.props.request(params); this.timeoutInstance = setTimeout(() => { if (!this.loadingOver) { this.setState({ status: 'loading' }); } }, 300); } /** * 请求成功的函数 */ public success(data: any, status: boolean): void { let temp; if (status) { this.data = data[this.props.dataKey]; if (this.data) { if (this.data.length === undefined || this.data.length) { temp = 'complete'; } else { temp = 'empty'; } } else { temp = 'empty'; } } else { temp = 'fail'; } this.loadingOver = true; this.setState({ status: temp, updateId: this.state.updateId + 1 }); } public timeoutCallback(): void { this.data = undefined; this.setState({ status: 'timeout', updateId: this.state.updateId + 1 }); } public render(): JSX.Element { return (
{this.statusRender()}
); } } export default View;