我使用rc-tree,一个版本的tree.js做出反应,我不知道如何创建一个方法,当检查树项时,更改该元素,父项及其子项的属性。
例如:
如果我点击New Folder1更改New Folder1项目上的选中值, 新的Folder2,新的Folder3,最后是layer12。
如果我点击layer12更改了layer12,New Folder3上的选中值, 新文件夹2,最后是新文件夹。
如果我点击Folder2上的新Folder2更改选中的值, Folder1,Folder3,最后是layer12。
这是一个json架构:
{
"name": "New Folder1",
"key": "0-625",
"isLeaf": false,
"type": "folder",
"expanded": false,
"checked": true,
"children": [{
"name": "New Folder2",
"key": "0-629",
"isLeaf": false,
"type": "folder",
"expanded": false,
"checked": true,
"children": [{
"name": "New Folder3",
"key": "0-623",
"isLeaf": false,
"type": "folder",
"expanded": false,
"checked": true,
"children": [{
"name": "layer12",
"key": "0-99",
"isLeaf": true,
"type": "layer",
"checked": true
}]
}]
}]
},
我发现这个方法在你检查时查找节点和树上的项目。但是如何更改子节点和父节点。
function getNodeByKey(key, node){
var reduce = [].reduce;
function runner(result, node){
if(result || !node) return result;
return node.key === key && node || //is this the proper node?
runner(null, node.children) || //process this nodes children
reduce.call(Object(node), runner, result); //maybe this is some ArrayLike Structure
}
return runner(null, node);
}
编辑:
在React中,您需要使用ref属性才能访问节点元素,然后您可以使用javascript:reactjs
访问子节点和父节点要访问儿童和家长,我想我必须使用childNodes
,parentNode
,nextSibling
和previousSibling
。
但如何使用ref属性???因为它是一个节点数组
render() {
const loop = (data) => {
return data.map((item) => {
if (item.children && item.children.length) {
return <TreeNode ref={this.myRef} title={item.name} key={item.key} checked={item.checked} >{loop(item.children)}</TreeNode>;
}
return (
<TreeNode ref={this.myRef} title={item.name} key={item.key} isLeaf={item.isLeaf} checked={item.checked} />
);
});
};
return (
<div className="draggable-container">
<Tree
// Expand
expandedKeys={this.state.expandedKeys}
onExpand={this.onExpand} autoExpandParent={this.state.autoExpandParent}
// Draggable
draggable
onDragStart={this.onDragStart}
onDragEnter={this.onDragEnter}
onDrop={this.onDrop}
// Select && Check
onSelect={this.onSelect}
checkable onCheck={this.onCheck} checkedKeys={this.state.checkedKeys} >
{ loop(this.state.treeData) }
</Tree>
</div>
);
}
onCheck = (checkedKeys, event) => {
how can get node checked??? it always returns last node
const node = this.myRef.current;
console.log(node)
}
答案 0 :(得分:1)
所以...关于你的&#39; ref&#39;问题:您将它们全部分配给同一个变量,您应该为每个节点生成ref-variable:
this.myRefs = {};
<TreeNode ref={itemRef=>this.myRefs[item.key]=itemRef} title={item.name} key={item.key} checked={item.checked} >{loop(item.children)}</TreeNode>
因此,您可以通过其密钥访问每个节点。
实现它的另一种方法是分配更有用的键:
{
"name": "New Folder1",
"key": "0",
"isLeaf": false,
"type": "folder",
"expanded": false,
"checked": true,
"children": [{
"name": "New Folder2",
"key": "0.0",
"isLeaf": false,
"type": "folder",
"expanded": false,
"checked": this.state.keysCheckedStatus['0.0'],
"children": [{
"name": "New Folder3",
"key": "0.0.0",
"isLeaf": false,
"type": "folder",
"expanded": false,
"checked": this.state.keysCheckedStatus['0.0.0'],
"children": [{
"name": "layer12",
"key": "0.0.0.0",
"isLeaf": true,
"type": "layer",
"checked": this.state.keysCheckedStatus['0.0.0.0']
},{
"name": "layer13",
"key": "0.0.0.1",
"isLeaf": true,
"type": "layer",
"checked": this.state.keysCheckedStatus['0.0.0.1']
}]
}]
}]
}
onCheck = (checkedKeys, event) => {
let keysCheckedStatus = this.state.keysCheckedStatus;
for(let key in checkedKeys){
let connectedKeys= Object.keys(this.state.keysCheckedStatus)
.filter(k=> (k.length > key.length) && k.startsWith(key)) || (key.startsWith(k));
for(let connectedKey in connectedKeys){
keysCheckedStatus[connectedKey]=true;
}
}
this.setState({keysCheckedStatus});
}
答案 1 :(得分:0)
这是我的解决方案,因为我的想法是使用所有树信息节点修改treeData:
onCheck = (checkedKeys, event) => {
// console.log(this.treeData);
const checkedKey = event.node.props.eventKey;
this.updateItemChecked(checkedKey);
this.setState({ checkedKeys: checkedKeys }, () => {
this.props.parentTree(this.treeData);
});
}
updateItemChecked = (key) => {
var result = getNodeByKey(key, this.treeData);
if (result.type.localeCompare('folder') !== 0) {
if (result.checked === true ) {
result.checked = false;
} else {
result.checked = true;
}
} else {
this.checkIfFolderHasItem(result);
}
}
checkIfFolderHasItem = (result) => {
if ( result.children && result.children.length > 0) {
result.children.forEach( (item) => {
if (item.type.localeCompare('folder') !== 0) {
this.updateItemChecked(item.key);
} else {
this.checkIfFolderHasItem(item);
}
});
}
}
// Expand
onExpand = (expandedKeys, event) => {
// console.log('onExpand', expandedKeys);
const checkedKey = event.node.props.eventKey;
this.updateFolderExpanded(checkedKey);
this.setState({ expandedKeys, autoExpandParent: false }, ()=> {
this.props.parentTree(this.treeData);
});
}
updateFolderExpanded = (key) => {
var result = getNodeByKey(key, this.treeData);
if (result.type.localeCompare('folder') === 0) {
if (result.expanded === true ) {
result.expanded = false;
} else {
result.expanded = true;
}
}
}
render() {
const loop = (data) => {
return data.map((item) => {
if (item.children && item.children.length) {
return <TreeNode title={item.name} key={item.key} checked={item.checked} >{loop(item.children)}</TreeNode>;
}
return (
<TreeNode title={item.name} key={item.key} isLeaf={item.isLeaf} checked={item.checked} />
);
});
};
return (
<div className="draggable-container">
{
// (this.state.showModal) ? <TreeModal show={this.state.showModal} info={this.state.selected} treeData={this.state.treeData} parentTreeModal={this.doParentTreeModal} /> : null
}
<Tree
// Expand
expandedKeys={this.state.expandedKeys}
onExpand={this.onExpand} autoExpandParent={this.state.autoExpandParent}
// Draggable
draggable
onDragStart={this.onDragStart}
onDragEnter={this.onDragEnter}
onDrop={this.onDrop}
// Select && Check
onSelect={this.onSelect}
checkable onCheck={this.onCheck} checkedKeys={this.state.checkedKeys} >
{ loop(this.state.treeData) }
</Tree>
</div>
);
}
JSON示例:
[
{
"name": "Capas1",
"key": "0-23",
"isLeaf": false,
"type": "folder",
"expanded": true,
"children": [{
"name": "sectores",
"key": "0-20",
"isLeaf": true,
"type": "layer",
"checked": true
},
{
"name": "distribucion",
"key": "0-22",
"isLeaf": true,
"type": "layer",
"checked": false
}]
},
{
"name": "Nueva Carpeta0",
"key": "0-624",
"isLeaf": false,
"type": "folder",
"expanded": false,
"checked": false
},
{
"name": "Nueva Carpeta1",
"key": "0-625",
"isLeaf": false,
"type": "folder",
"expanded": true,
"children": [{
"name": "Nueva Carpeta2",
"key": "0-629",
"isLeaf": false,
"type": "folder",
"expanded": true,
"children": [{
"name": "Nueva Carpeta3",
"key": "0-623",
"isLeaf": false,
"type": "folder",
"expanded": true,
"children": [{
"name": "distribucion33",
"key": "0-99",
"isLeaf": true,
"type": "layer",
"checked": true
}]
}]
}]
},
{
"name": "sectores1",
"key": "0-27",
"isLeaf": true,
"type": "layer",
"checked": true
},
{
"name": "sectores12",
"key": "0-89",
"isLeaf": true,
"type": "layer",
"checked": false
},
{
"name": "Capas 2",
"key": "0-588",
"isLeaf": false,
"type": "folder",
"expanded": false,
"children": [{
"name": "Capas 3",
"key": "0-589",
"isLeaf": false,
"type": "folder",
"expanded": false,
"children": [{
"name": "Prueba",
"key": "0-36",
"isLeaf": true,
"type": "layer",
"checked": false
}]
}]
}
]