// {value: 'aaa', label: 'bbb'}
// onNextPage(this.word, this.pages, FILTER_LENGTH);
// 搜索词、页数、页面数据量
import { Select } from "antd";
import debounce from "lodash/debounce";
import React, { Component } from "react";
const { Option } = Select;
const FILTER_LENGTH = 50;
class MyScrollSelect extends Component{
filter_options = []; // 过滤规则选项
pages = 1;
word = '';
static defaultProps = {
placeholder: '请选择该字段',
options: [],
has_all_key: false, // 需不需要全部选项,全部选项默认ID为-1
FILTER_LENGTH: FILTER_LENGTH,
}
state = {
filter_options_for_show: [], // 过滤规则展示选项
has_init_value: true, // 需要对初始化数据处理
}
// 异步初始化
componentWillReceiveProps(nextProps) {
if (nextProps.options.length > 0 && this.state.has_init_value) {
setTimeout(() => {
this.filterOption('')
}, 0)
}
}
// 过滤列表
filterOption = async (input) => {
let options = [], filters = [], origin_options = [];
this.pages = 1;
this.word = input;
this.setState({ filter_options_for_show: []});
// 支持远程
if (this.props.onNextPage) {
let data = await this.props.onNextPage(this.word, this.pages, this.props.FILTER_LENGTH);
if (data.length == 0) {
return
}
origin_options = data;
} else {
origin_options = this.props.options;
}
// 如果有默认值,就把默认值挪到第一个位置
if (this.props.value && this.state.has_init_value) {
let initIndex = -1;
for (let index in origin_options) {
if (origin_options[index].value == this.props.value) {
initIndex = index;
break;
}
}
origin_options.unshift(origin_options.splice(initIndex, 1)[0])
}
this.setState({ has_init_value: false });
filters = origin_options.filter(
(item) => {return (item.label.toLowerCase()).indexOf(input.toLowerCase()) > -1}
)
if (this.props.has_all_key) {
filters.unshift({value: -1, label: '全部'})
}
this.filter_options = filters;
options = filters.slice(0, this.props.FILTER_LENGTH)
this.setState({'filter_options_for_show': options })
}
// 循环获取
Scroll = async (e) => {
e.persist();
const { target } = e;
if (this.state.filter_options_for_show.length < this.props.FILTER_LENGTH * this.pages) {
return
}
if (target.scrollTop + target.offsetHeight === target.scrollHeight) {
// 支持远程
if (this.props.onNextPage) {
let data = await this.props.onNextPage(this.word, this.pages, this.props.FILTER_LENGTH);
if (data.length == 0) {
return
}
this.filter_options.concat(data);
}
this.pages += 1;
let content = this.filter_options.length - this.pages * this.props.FILTER_LENGTH;
if (content < -this.props.FILTER_LENGTH) { return }
let options = this.filter_options.slice(0, FILTER_LENGTH * this.pages);
this.setState({'filter_options_for_show': options})
setTimeout(() => {
target.scrollTop=target.scrollHeight - 1500;
})
}
}
focus = () => {
if (this.props.options.length > 0) {
this.pages = 1;
this.filterOption('')
}
}
filter = debounce(this.filterOption, 100);
render () {
return (
<Select
{...this.props}
showSearch
onChange={this.props.onChange}
onPopupScroll={this.Scroll}
placeholder={this.props.placeholder}
onFocus={this.focus}
filterOption={false}
onSearch={(input, option) =>{this.filter(input)}}
optionLabelProp="label"
>
{
this.state.filter_options_for_show.map((option) => {
return (
<Option key={option.value} value={option.value} label={option.label}>
{
this.props.has_hot_tags && option.is_hot && <i className={'iconhuo iconfont red margin-0'}></i>
}
{option.label}
</Option>
)
})
}
</Select>
)
}
}
export default MyScrollSelect;
网友评论