// actions.js
import ajax from 'vj-ajax';
export const RECEIVE_TREENODE_SUCCESS = 'RECEIVE_TREENODE_SUCCESS';
export const RECEIVE_TREENODE_FAIL = 'RECEIVE_TREENODE_FAIL';
const fetchTreeNode = (pid = 0, loadedIds) => dispatch => {
if (loadedIds.indexOf(pid) > -1) { // pid 为请求的节点id
return new Promise(resolve => {
resolve();
});
};
return ajax({
url: 'xxx',
data: {
pid,
},
}).then(data => {
dispatch({
type: RECEIVE_TREENODE_SUCCESS,
text: '树节点请求成功',
data: {
list: data.list || [], // node的数组
pid: pid,
}
});
}).catch(error => {
dispatch(fail(RECEIVE_TREENODE_FAIL, '树节点请求失败', error));
});
};
export default { fetchTreeNode }
// reducers.js
import { RECEIVE_TREENODE_SUCCESS, RECEIVE_TREENODE_FAIL } from './actions.js';
const treeInitData = {
fetching: true,
loadedIds: [],
treeData: [],
};
// 查找node节点
const findNode = (data, id) => {
let parent = null
const loop = data => {
for (var i = 0, l = data.length ; i < l; i++) {
if (data[i].id == id) {
parent = data[i];
break;
};
if (data[i].children) {
loop(data[i].children);
};
};
};
loop(data);
return parent;
};
const filterNodes = (state, nextData) => {
let { treeData, loadedIds } = state;
let { list, pid } = nextData;
let parentNode = findNode(treeData, pid);
const filter = data => {
for (var i = 0, l = data.length; i < l; i++) {
data[i].isLeaf = data[i].is_leaf || false;
data[i].parentId = data[i].parent_id || 0; // 按需
data[i].key = parentNode ? `${parentNode.key}-${data[i].id}` : `${data[i].id}`;
data[i].fullName = parentNode ? `${parentNode.fullName}->-${data[i].name}` : `${data[i].name}`; // 按需
data[i].sortId = data[i].sort_id || 0; // 按需
// 在这里处理TreeNode props
};
};
filter(list);
if (parentNode) {
parentNode.children = list;
} else {
treeData = list;
};
loadedIds.push(pid);
return {
treeData,
loadedIds,
};
};
const tree = (state = treeInitData, action) => {
switch (action.type) {
case RECEIVE_TREENODE_SUCCESS:
return {
...filterNodes(state, action.data),
success: true,
fetching: false,
};
case RECEIVE_TREENODE_FAIL:
return {
...state,
error: action.error,
success: false,
fetching: false,
};
default:
return state;
};
};
export default { tree };
// VjTree.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import Tree from 'vj-tree';
import actions from './actions.js';
class VjTree extends Component {
constructor(props) {
super(props);
};
handleLoadData = node => {
const { loadedIds, fetchTreeNode } = this.props;
fetchTreeNode(node.props.id, loadedIds);
};
render() {
const { tree: { treeData } } = this.props;
return (
<Tree
treeData={treeData}
loadData={this.handleLoadData}
/>
);
};
};
const mapStateToProps = state => {
const { tree } = state;
return { tree };
};
export default connect(mapStateToProps, actions)(VjTree);