import * as React from 'react'; import {BasicConfig, BasicContainer, BasicContainerPropsInterface} from '../../render/core/Container/types'; import componentLoader from '../../render/util/componentLoader'; import {AutoComplete} from '@native-ads/antd'; import {isPlainObject, debounce} from 'lodash'; import {compileExpressionString, isExpression} from '../../render/util/vm'; import {request} from '../../render/services/api'; import {parseExpressString} from '../../render/parser/index'; export interface RemoteConfig { /** * 请求地址 */ url: string; /** * 请求方法 */ method: string; /** * 请求数据 */ data: Object; /** * 映射接口值到dataSource */ retMapping: string; } export class AutoCompleteConfig extends BasicConfig { /** * 数据模型Key */ name: string; /** * 初始化的默认值 */ defaultValue: string; /** * 下拉数据源 */ dataSource: string[]; /** * 动态加载数据配置 */ loadDataConfig?: RemoteConfig; } export class AutoCompletePropsInterface extends BasicContainerPropsInterface { info: AutoCompleteConfig; } export interface AutoCompleteStateInterface { dataSource: string[]; } export class AbstractAutoComplete extends BasicContainer { constructor(props: AutoCompletePropsInterface) { super(props); this.state = { dataSource: [] }; this.handleSearch = this.handleSearch.bind(this); this.requestData = debounce(this.requestData.bind(this), 300, { 'trailing': true }); } componentWillMount() { if (this.props.$setData && this.props.info.defaultValue) { const $setData = this.props.$setData; $setData(this.props.info.name, this.props.info.defaultValue); } } private handleSearch(value: string) { let info = this.props.info; if (info.loadDataConfig) { this.requestData(value, info.loadDataConfig); } else { console.info('如果你想通过输入动态请求数据,那么请使用loadDataConfig属性'); } } private requestData(searchValue: string, config: RemoteConfig) { if (!isPlainObject(config)) { console.error('loadDataConfig 属性必须是一个纯对象'); } let runTime = this.getRuntimeContext(); let sendData = compileExpressionString(config.data, { ...runTime, $args: { search: searchValue } }); request(config.url, { url: config.url, method: config.method, data: sendData }).then(response => { let data = response.data; let source: string[]; if (isExpression(config.retMapping)) { source = parseExpressString(config.retMapping, { ...runTime, $output: data }); } else { source = data; } this.setState({ dataSource: source }); }); } render() { let info = this.getPropsInfo(this.props.info); if (!info.name) { return this.errorReport('name property is required for autoComplete component', 'div'); } if (!this.isUnderContainerEnv()) { return this.errorReport('autoComplete component should be under container component control', 'div'); } let dataSource; if (info.loadDataConfig) { dataSource = this.state.dataSource; } else { dataSource = info.dataSource; } return ( { if (this.props.$setData) { this.props.$setData(info.name, val); } this.commonEventHandler('onSelect', { value: val }); }} onSearch={this.handleSearch} /> ); } } componentLoader.addComponent('autoComplete', AbstractAutoComplete, AutoCompletePropsInterface);