修复若干bug
This commit is contained in:
parent
9bf5b060ca
commit
1175612369
@ -2,14 +2,16 @@
|
|||||||
|
|
||||||
### 1.2.0
|
### 1.2.0
|
||||||
|
|
||||||
*2020-11-25*
|
*2020-11-26*
|
||||||
|
|
||||||
#### 新增
|
#### 新增
|
||||||
|
|
||||||
- 单选图标自定义
|
- 图标自定义
|
||||||
- 新增实例方法`getTreeValue`, 用于获取树结构下的父节点和半选节点
|
- 新增实例方法`getTreeValue`, 用于获取树结构下的父节点和半选节点
|
||||||
|
- 新增实例方法`changeExpandedKeys`, 用于操作树结构的节点展开状态
|
||||||
- 新增实例方法`enable`, `disable`, 动态操作选项的启用禁用
|
- 新增实例方法`enable`, `disable`, 动态操作选项的启用禁用
|
||||||
- 新增配置`layReqText`, 表单验证, 同`layui`的`lay-reqText`
|
- 新增配置`layReqText`, 表单验证, 同`layui`的`lay-reqText`
|
||||||
|
- 新增全局方法`arr2tree`, 用于把列表数据转化为树状结构
|
||||||
|
|
||||||
#### Bug fixes
|
#### Bug fixes
|
||||||
|
|
||||||
@ -18,6 +20,8 @@
|
|||||||
- 修改`update`方法无法更新远程
|
- 修改`update`方法无法更新远程
|
||||||
- 修复tree模式下非严格模式搜索异常
|
- 修复tree模式下非严格模式搜索异常
|
||||||
- 修复tree模式下工具条操作异常
|
- 修复tree模式下工具条操作异常
|
||||||
|
- 修复tree模式下`initValue`赋值数据错乱
|
||||||
|
- 修复tree模式下`append`和`delete`方法不更新父节点状态
|
||||||
|
|
||||||
|
|
||||||
### 1.1.9
|
### 1.1.9
|
||||||
|
2
dist/static/2.js
vendored
2
dist/static/2.js
vendored
File diff suppressed because one or more lines are too long
2
dist/static/3.js
vendored
2
dist/static/3.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xm-select.js
vendored
2
dist/xm-select.js
vendored
File diff suppressed because one or more lines are too long
@ -39,6 +39,9 @@ tree: {
|
|||||||
<br/><br/>
|
<br/><br/>
|
||||||
<input type="checkbox" name="hidden" lay-filter="hidden" lay-skin="primary" title="隐藏父节点图标">
|
<input type="checkbox" name="hidden" lay-filter="hidden" lay-skin="primary" title="隐藏父节点图标">
|
||||||
<input type="checkbox" name="custom" lay-filter="custom" lay-skin="primary" title="自定义图标">
|
<input type="checkbox" name="custom" lay-filter="custom" lay-skin="primary" title="自定义图标">
|
||||||
|
<input type="checkbox" name="all" lay-filter="all" lay-skin="primary" title="展开所有节点">
|
||||||
|
<input type="checkbox" name="close" lay-filter="close" lay-skin="primary" title="闭合所有节点">
|
||||||
|
<input type="checkbox" name="key3" lay-filter="key3" lay-skin="primary" title="展开指定节点">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="margin-top: 20px">间距</div>
|
<div style="margin-top: 20px">间距</div>
|
||||||
@ -86,6 +89,27 @@ layui.form.on('checkbox(custom)', function(data){
|
|||||||
layui.form.render();
|
layui.form.render();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//展开所有节点
|
||||||
|
layui.form.on('checkbox(all)', function(data){
|
||||||
|
if(data.elem.checked){
|
||||||
|
demo1.changeExpandedKeys(true)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//闭合所有节点
|
||||||
|
layui.form.on('checkbox(close)', function(data){
|
||||||
|
if(data.elem.checked){
|
||||||
|
demo1.changeExpandedKeys(false)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//展开指定节点
|
||||||
|
layui.form.on('checkbox(key3)', function(data){
|
||||||
|
if(data.elem.checked){
|
||||||
|
demo1.changeExpandedKeys([ -3 ])
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
layui.slider.render({
|
layui.slider.render({
|
||||||
elem: '#slideTest1',
|
elem: '#slideTest1',
|
||||||
min: 10,
|
min: 10,
|
||||||
|
@ -15,6 +15,7 @@ var demo1 = xmSelect.render({
|
|||||||
showLine: true,
|
showLine: true,
|
||||||
indent: 20,
|
indent: 20,
|
||||||
expandedKeys: [ -3 ],
|
expandedKeys: [ -3 ],
|
||||||
|
simple: true,
|
||||||
},
|
},
|
||||||
toolbar: {
|
toolbar: {
|
||||||
show: true,
|
show: true,
|
||||||
|
@ -208,6 +208,7 @@ list: [ "ALL", "CLEAR",
|
|||||||
| render | 渲染多选 | (options: 配置项) | 实例对象 |
|
| render | 渲染多选 | (options: 配置项) | 实例对象 |
|
||||||
| get | 获取页面中已经渲染的多选 | (filter: 过滤`el`, single: 是否返回单实例) | 符合条件的实例数组 |
|
| get | 获取页面中已经渲染的多选 | (filter: 过滤`el`, single: 是否返回单实例) | 符合条件的实例数组 |
|
||||||
| batch | 批量操作已渲染的多选 | (filter: 过滤`el`, method: 方法, ...方法参数) | 符合条件的实例数组 |
|
| batch | 批量操作已渲染的多选 | (filter: 过滤`el`, method: 方法, ...方法参数) | 符合条件的实例数组 |
|
||||||
|
| arrr2tree | 把列表数据转化为树状结构 | (arr: 数据, pid: 父节点ID的key, id: 对应key, children: 对应key, topParentId: 顶级节点的ID) | 符合条件的数组 |
|
||||||
|
|
||||||
```
|
```
|
||||||
//render 使用方式
|
//render 使用方式
|
||||||
@ -251,5 +252,6 @@ xmSelect.render()后会返回一个xmSelect对象, 可以进行方法调用
|
|||||||
| update | 更新多选选中, reset不保留 | (options: 见配置项) |
|
| update | 更新多选选中, reset不保留 | (options: 见配置项) |
|
||||||
| warning | 警告 | (color: 默认同theme.maxColor, sustain: 是否持续显示) |
|
| warning | 警告 | (color: 默认同theme.maxColor, sustain: 是否持续显示) |
|
||||||
| getTreeValue | 树节点模式下获取数据, v1.2.0 新增 | (leafOnly: 是否只是叶子节点,默认值为 false, includeHalfChecked: 是否包含半选节点,默认值为 false) |
|
| getTreeValue | 树节点模式下获取数据, v1.2.0 新增 | (leafOnly: 是否只是叶子节点,默认值为 false, includeHalfChecked: 是否包含半选节点,默认值为 false) |
|
||||||
|
| changeExpandedKeys | 树模式下更新节点展开状态, v1.2.0 新增 | (keys: true-全部展开, false-全部关闭, 数组-展开的节点值) |
|
||||||
| enable | 启用选项, disabled=false, v1.2.0 新增 | (array: 想要启用的选项数组) |
|
| enable | 启用选项, disabled=false, v1.2.0 新增 | (array: 想要启用的选项数组) |
|
||||||
| disable | 禁用用选项, disabled=true, v1.2.0 新增 | (array: 想要禁用的选项数组) |
|
| disable | 禁用用选项, disabled=true, v1.2.0 新增 | (array: 想要禁用的选项数组) |
|
||||||
|
@ -40,7 +40,7 @@ class Framework extends Component{
|
|||||||
if(refresh){
|
if(refresh){
|
||||||
let dataObj = {};
|
let dataObj = {};
|
||||||
let flatData = [];
|
let flatData = [];
|
||||||
this.load(data, dataObj, flatData);
|
this.load(data, dataObj, flatData, null, 0, initValue ? initValue.map(i => typeof i === 'object' ? i[prop.value] : i) : null);
|
||||||
sels = this.exchangeValue(initValue ? initValue : Object.keys(dataObj).filter(key => {
|
sels = this.exchangeValue(initValue ? initValue : Object.keys(dataObj).filter(key => {
|
||||||
let item = dataObj[key]
|
let item = dataObj[key]
|
||||||
return item[prop.selected] === true
|
return item[prop.selected] === true
|
||||||
@ -88,15 +88,15 @@ class Framework extends Component{
|
|||||||
|
|
||||||
exchangeValue(arr, dataObj = this.state.dataObj){
|
exchangeValue(arr, dataObj = this.state.dataObj){
|
||||||
let list = arr.map(sel => typeof sel === 'object' ? { ...sel, __node: {} } : dataObj[sel]).filter(a => a)
|
let list = arr.map(sel => typeof sel === 'object' ? { ...sel, __node: {} } : dataObj[sel]).filter(a => a)
|
||||||
let filterGroup = true, { tree } = this.props;
|
let filterGroup = true, { tree, cascader } = this.props;
|
||||||
if(tree.show && tree.strict === false){
|
if(tree.show && tree.strict === false || cascader.show && cascader.strict === false){
|
||||||
filterGroup = false;
|
filterGroup = false;
|
||||||
}
|
}
|
||||||
filterGroup && (list = list.filter(item => item[this.props.prop.optgroup] !== true))
|
filterGroup && (list = list.filter(item => item[this.props.prop.optgroup] !== true))
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
value(sels, show, listenOn){
|
value(sels, show, listenOn, jsChangeData){
|
||||||
if(show !== false && show !== true){
|
if(show !== false && show !== true){
|
||||||
show = this.state.show;
|
show = this.state.show;
|
||||||
}
|
}
|
||||||
@ -114,7 +114,7 @@ class Framework extends Component{
|
|||||||
this.clearAndReset(data, changeData);
|
this.clearAndReset(data, changeData);
|
||||||
changeData = this.init({ data, prop }, true);
|
changeData = this.init({ data, prop }, true);
|
||||||
}
|
}
|
||||||
this.resetSelectValue(changeData, changeData, true, listenOn);
|
this.resetSelectValue(changeData, jsChangeData ? jsChangeData : changeData, true, listenOn);
|
||||||
this.setState({ show })
|
this.setState({ show })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,12 +127,17 @@ class Framework extends Component{
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
load(data, dataObj, flatData, parent, level = 0){
|
load(data, dataObj, flatData, parent, level = 0, initValue){
|
||||||
const { prop, tree } = this.props;
|
const { prop, tree, cascader } = this.props;
|
||||||
const { children, optgroup, value, selected, disabled } = prop;
|
const { children, optgroup, value, selected, disabled } = prop;
|
||||||
data.forEach(item => {
|
data.forEach(item => {
|
||||||
//数据提取/处理
|
//数据提取/处理
|
||||||
item.__node = { parent, level, loading: item.__node && item.__node.loading },
|
item.__node = { parent, level, loading: item.__node && item.__node.loading };
|
||||||
|
|
||||||
|
if(initValue){
|
||||||
|
delete item[selected]
|
||||||
|
initValue.find(i => i === item[value]) && (item[selected] = true)
|
||||||
|
}
|
||||||
|
|
||||||
dataObj[item[value]] = item;
|
dataObj[item[value]] = item;
|
||||||
flatData.push(item);
|
flatData.push(item);
|
||||||
@ -141,12 +146,12 @@ class Framework extends Component{
|
|||||||
if(child && isArray(child)){
|
if(child && isArray(child)){
|
||||||
let len = child.length;
|
let len = child.length;
|
||||||
if(len > 0){
|
if(len > 0){
|
||||||
this.load(child, dataObj, flatData, item, level + 1);
|
this.load(child, dataObj, flatData, item, level + 1, initValue);
|
||||||
|
|
||||||
//是否包含子节点
|
//是否包含子节点
|
||||||
item[optgroup] = true;
|
item[optgroup] = true;
|
||||||
//严格的父子结构
|
//严格的父子结构
|
||||||
if(tree.strict){
|
if(tree.strict || cascader.strict){
|
||||||
if(item[selected] === true){
|
if(item[selected] === true){
|
||||||
delete item[selected]
|
delete item[selected]
|
||||||
child.forEach(c => c[selected] = true)
|
child.forEach(c => c[selected] = true)
|
||||||
@ -372,30 +377,30 @@ class Framework extends Component{
|
|||||||
}else
|
}else
|
||||||
//聚焦label搜索框
|
//聚焦label搜索框
|
||||||
if(type === 'labelSearchBlur'){
|
if(type === 'labelSearchBlur'){
|
||||||
this.labelView.blur(data);
|
this.labelRef.blur(data);
|
||||||
}else
|
}else
|
||||||
//聚焦label搜索框
|
//聚焦label搜索框
|
||||||
if(type === 'labelSearch'){
|
if(type === 'labelSearch'){
|
||||||
this.generalView.labelSearch(data);
|
this.generalRef.labelSearch(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
append(arr){
|
append(arr){
|
||||||
let changeData = this.exchangeValue(arr);
|
let changeData = this.exchangeValue(arr);
|
||||||
this.resetSelectValue(mergeArr(changeData, this.state.sels, this.props.prop), changeData, true);
|
this.value(mergeArr(changeData, this.state.sels, this.props.prop), this.props.show, true, changeData);
|
||||||
}
|
}
|
||||||
|
|
||||||
del(arr){
|
del(arr){
|
||||||
let value = this.props.prop.value;
|
let value = this.props.prop.value;
|
||||||
let sels = this.state.sels;
|
let sels = this.state.sels;
|
||||||
arr = this.exchangeValue(arr);
|
let changeData = this.exchangeValue(arr);
|
||||||
arr.forEach(v => {
|
changeData.forEach(v => {
|
||||||
let index = sels.findIndex(item => item[value] === v[value]);
|
let index = sels.findIndex(item => item[value] === v[value]);
|
||||||
if(index != -1){
|
if(index != -1){
|
||||||
sels.splice(index, 1);
|
sels.splice(index, 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.resetSelectValue(sels, arr, false);
|
this.value(sels, this.props.show, true, changeData)
|
||||||
}
|
}
|
||||||
|
|
||||||
auto(arr){
|
auto(arr){
|
||||||
@ -404,6 +409,14 @@ class Framework extends Component{
|
|||||||
sels.length == arr.length ? this.del(arr) : this.append(arr);
|
sels.length == arr.length ? this.del(arr) : this.append(arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
changeExpandedKeys(expandedKeys){
|
||||||
|
const { tree, prop } = this.props;
|
||||||
|
const { dataObj, flatData } = this.state;
|
||||||
|
if(tree.show){
|
||||||
|
this.treeRef.init({ dataObj, flatData, prop, tree: { expandedKeys } })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//组件将要接收新属性
|
//组件将要接收新属性
|
||||||
componentWillReceiveProps(props){
|
componentWillReceiveProps(props){
|
||||||
this.init(props, props.updateData);
|
this.init(props, props.updateData);
|
||||||
@ -446,20 +459,20 @@ class Framework extends Component{
|
|||||||
const bodyProps = { ...config, data, dataObj, flatData, sels, ck: this.itemClick.bind(this), show, onReset: this.onReset.bind(this) }
|
const bodyProps = { ...config, data, dataObj, flatData, sels, ck: this.itemClick.bind(this), show, onReset: this.onReset.bind(this) }
|
||||||
|
|
||||||
//渲染组件
|
//渲染组件
|
||||||
let Body = content ? <Custom { ...bodyProps } /> : tree.show ? <Tree { ...bodyProps } /> : config.cascader.show ? <Cascader { ...bodyProps } /> : <General { ...bodyProps } ref={ ref => this.generalView = ref } />;
|
let Body = content ? <Custom { ...bodyProps } /> : tree.show ? <Tree { ...bodyProps } ref={ ref => this.treeRef = ref } /> : config.cascader.show ? <Cascader { ...bodyProps } /> : <General { ...bodyProps } ref={ ref => this.generalRef = ref } />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<xm-select { ...xmSelectProps } >
|
<xm-select { ...xmSelectProps } >
|
||||||
<input class="xm-select-default"
|
<input class="xm-select-default"
|
||||||
lay-verify={ config.layVerify }
|
lay-verify={ config.layVerify }
|
||||||
lay-verType={ config.layVerType }
|
lay-verType={ config.layVerType }
|
||||||
lay-reqText={ config.layReqText }
|
lay-reqText={ config.layReqText }
|
||||||
name={ config.name }
|
name={ config.name }
|
||||||
value={ sels.map(item => item[prop.value]).join(',') }
|
value={ sels.map(item => item[prop.value]).join(',') }
|
||||||
></input>
|
></input>
|
||||||
<i class={ show ? 'xm-icon xm-icon-expand' : 'xm-icon' } />
|
<i class={ show ? 'xm-icon xm-icon-expand' : 'xm-icon' } />
|
||||||
{ sels.length === 0 && <div class="xm-tips">{ config.tips }</div> }
|
{ sels.length === 0 && <div class="xm-tips">{ config.tips }</div> }
|
||||||
<Label { ...labelProps } ref={ ref => this.labelView = ref } />
|
<Label { ...labelProps } ref={ ref => this.labelRef = ref } />
|
||||||
<div class={ ['xm-body', bodyClass, config.model.type, show ? '':'dis', ].join(' ') } ref={ ref => this.bodyView = ref}>
|
<div class={ ['xm-body', bodyClass, config.model.type, show ? '':'dis', ].join(' ') } ref={ ref => this.bodyView = ref}>
|
||||||
{ Body }
|
{ Body }
|
||||||
</div>
|
</div>
|
||||||
|
@ -29,6 +29,8 @@ class Tree extends Component{
|
|||||||
let keys = [];
|
let keys = [];
|
||||||
if(tree.expandedKeys === true){
|
if(tree.expandedKeys === true){
|
||||||
keys = flatData.filter(item => item[optgroup] === true).map(item => item[value])
|
keys = flatData.filter(item => item[optgroup] === true).map(item => item[value])
|
||||||
|
}else if(tree.expandedKeys === false){
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
tree.expandedKeys.forEach(key => {
|
tree.expandedKeys.forEach(key => {
|
||||||
keys.push(key);
|
keys.push(key);
|
||||||
|
@ -213,6 +213,14 @@ class xmOptions {
|
|||||||
|
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 动态操作树状结构的节点展开状态
|
||||||
|
*/
|
||||||
|
changeExpandedKeys(keys){
|
||||||
|
childData[this.options.el].changeExpandedKeys(keys)
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 动态启用一些选项
|
* 动态启用一些选项
|
||||||
|
17
src/index.js
17
src/index.js
@ -45,12 +45,27 @@ export default {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let keys = Object.keys(datas)
|
let keys = Object.keys(datas)
|
||||||
let list = (method ? keys.filter(method) : keys).map(key => datas[key]).filter(instance => selector(instance.options.el));
|
let list = (method ? keys.filter(method) : keys).map(key => datas[key]).filter(instance => selector(instance.options.el));
|
||||||
|
|
||||||
return single ? list[0] : list;
|
return single ? list[0] : list;
|
||||||
},
|
},
|
||||||
batch(filter, method) {
|
batch(filter, method) {
|
||||||
let args = [...arguments];
|
let args = [...arguments];
|
||||||
args.splice(0, 2);
|
args.splice(0, 2);
|
||||||
return this.get(filter).map(instance => instance[method](...args));
|
return this.get(filter).map(instance => instance[method](...args));
|
||||||
|
},
|
||||||
|
arr2tree(arr, pid, id, children, topParentId){
|
||||||
|
arr.forEach(item => {
|
||||||
|
if(item[pid] != topParentId){
|
||||||
|
let parent = arr.find(i => i[id] === item[pid])
|
||||||
|
if(parent){
|
||||||
|
if(!parent[children]){
|
||||||
|
parent[children] = [];
|
||||||
|
}
|
||||||
|
parent[children].push(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return arr.filter(i => i[pid] == topParentId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user