UNPKG

hc-components-test

Version:

基于react的通用组件库

150 lines (135 loc) 4.07 kB
import React from 'react'; import PropTypes from 'prop-types'; import localeContext from '../../localeContext'; @localeContext('DataSet', { errorMessage: '需要传入ajax对象' }) export class DataSet extends React.PureComponent { static formatter = {}; static themeOptions = {}; static theme = (themeOptions) => { DataSet.themeOptions = themeOptions; } static propTypes = { type: PropTypes.string, component: PropTypes.element, data: PropTypes.object, actions: PropTypes.object, ajax: PropTypes.object, getResolver: PropTypes.func, defaultValue: PropTypes.string, format: PropTypes.string, formatter: PropTypes.func, children: PropTypes.any } static defaultProps = { data: {} } constructor(props, context) { super(props, context); this.state = {}; this.stateUpdater = {}; this._ajax = props.ajax; if (props.getResolver) { const resolver = props.getResolver(props.defaultValue); resolver.then(iState => { this.setState(iState); }); } /** * prop = { * value: Object | Function, * format: String, * formatter: Function, * setter: String | Function * } */ Object .keys(props.data) .forEach(name => { const prop = props.data[name]; const originValue = typeof prop.value === 'function' ? prop.value.call(this, this.props) : prop.value; const formatter = this.getFormatter(props.formatter, name); // formatter是一系列解决组件schema的格式化函数 if (formatter) { this.state[name] = formatter.call(this, prop.schema, originValue); } else { this.state[name] = originValue; } if (prop.setter) { this.stateUpdater[prop.setter] = (updateFn, callback) => (this.setState(({stateName}) => () => { let newValue = typeof updateFn === 'function' ? updateFn.call(this, stateName) : updateFn; const formatter = this.getFormatter(props.formatter, name); if (formatter) { newValue = formatter.call(this, prop.schema, newValue); } return newValue; }, callback)); } }); } handleResolve = (value, params) => { if (this.props.getResolver) { const resolver = this.props.getResolver(value, params); resolver.then(iState => { this.setState(iState); }); } } getFormatter(formatter, name) { if (!formatter && DataSet.formatter) { const comFormatter = DataSet.formatter[this.props.format] || {}; formatter = comFormatter[name]; } return formatter; } getRealInstance() { return this._instance; } render() { let option = {}; let type; if (this.props.component) { type = this.props.component.name; if (type && DataSet.themeOptions[type]) { option = DataSet.themeOptions[type]; } if (this.props.children) { return ( <this.props.component ref={instance => this._instance = instance} {...option} {...this.props} {...this.state} {...this.stateUpdater}>{this.props.children}</this.props.component> ); } else { return (<this.props.component ref={instance => this._instance = instance} {...option} {...this.props} {...this.state} {...this.stateUpdater} />); } } else { type = this.props.children.type.name; if (type && DataSet.themeOptions[type]) { option = DataSet.themeOptions[type]; } return React.cloneElement(React.Children.only(this.props.children), { ref: instance => { this._instance = instance; if (typeof this.props.children.ref === 'function') { this.props.children.ref(instance); } }, ...option, ...this.props, ...this.state, ...this.stateUpdater }); } } }