1.2.3
Windows/Chrome 56
2.2.1
https://codepen.io/anon/pen/ryLLVq
随便点击一个节点,删除了该节点,查看控制台。
在 store.data 中数据未删除。
在 Tree 文档的 自定义节点内容 一节,里面用到了 append 和 remove 方法,但是下方 API 未写明。我给出的 codepen 中仅把官方例子中 JSX 改为 render 函数,删除节点时,DOM 上是显示移除了,但 store.data 数据没有变化。
同求啊,也遇到了这个问题,持续懵逼中,求大神解救
同求,今天折腾了一下午,问题也没有解决
同样遇到这个问题
话说难道是需要用到load加载么
提供半个解决方法。append可以用下面这个取代,remove怎么搞我也懵逼
append(store, data) {
// store.append({ id: id++, label: 'testtest', children: [] }, data); //无法改变data的
data.children.push({ id: id++, label: '测试', children: [] });
}
同样遇到此问题.
提供个解决思路:
通过$children获取到ELTree组件的_data.root.childNodes属性.里面存放有当前Tree的一些属性(填加/删除会反映到这里).可以在点击append或者remove之后.用上面获取到的tree obj 替换tree的data.
(我正在解决其中细节.这个思路已证可行)
折腾了差不多一天.不是从Eleme源码而是另外的角度解决了这个问题:
首先我发现,在append/remove节点之后,结果是会反映在ElTree(用VueDevTools查看)里的一些属性里的.比如_data.root.childNodes.所以在Append/Delete方法里动态获取它里面的我们想要的数据(id,label,childNodes).然后赋值给this.data就好了.
所以我就写了一个函数来做这件事:
testFunc(){
//我们想要的数据,在这里面.你可以打印出来研究一下.
let tempObj = this.$refs.treeParent.$children[0]['_data'].root.childNodes;
//在获取数据之前,需要深克隆一下上面的对象,因为后面我们需要直接处理该对象.
// DeepCopy函数来自https://zhuanlan.zhihu.com/p/23251162
function DeepCopy(obj) {
// Hash表 记录所有的对象引用关系
let map = new WeakMap();
function dp(obj) {
let result = null;
let keys = null,
key = null,
temp = null,
existObj = null;
existObj = map.get(obj);
// 如果这个对象已被记录则直接返回
if (existObj) {
return existObj;
}
keys = Object.keys(obj);
result = {};
// 记录当前对象
map.set(obj,result);
for (let i = 0; i < keys.length; i++) {
key = keys[i];
temp = obj[key];
// 如果字段的值也是一个对象则递归复制
if (temp && typeof temp === 'object') {
result[key] = dp(temp);
} else {
// 否则直接赋值给新对象
result[key] = temp;
}
}
return result;
}
return dp(obj);
}
//dealData方法处理对象,把对象变成{"id":123,"label":"test",childNodes:[]}的形式,会删除所有其他属性
function dealData(obj) {
for (let attr of Object.keys(obj)) {
if (attr != "data" && attr != "childNodes") {
delete obj[attr];
}
}
if (obj.hasOwnProperty('data')) {
obj.id = obj.data.id;
obj.label = obj.data.label;
delete obj.data;
}
for (let item in obj.childNodes) {
if(item){
dealData(obj.childNodes[item]);
};
}
}
//在上面DeepCopy时,把childNodes变成了object,但我们想要的是Array.所以本函数可以把它转换回来.
function objToArray(obj) {
let arr = [];
for (let item in obj.childNodes) {
if (item) {
arr.push(obj.childNodes[item]);
}
}
obj.childNodes = arr;
for (let a of arr) {
objToArray(a);
}
}
// data 模拟 this.data
let data = [];
for (const item of Object.values(tempObj)){
let copied = DeepCopy(item);
dealData(copied);
copied = JSON.parse(JSON.stringify(copied));
objToArray(copied);
data.push(copied);
}
// data里的数据是我们想要的.可以直接赋值给this.data来解决Element的这个Bug.
return data;
},
append(store,data) {
store.append({
id: id++,
label: 'test',
children: []
}, data);
let obj = this.testFunc();
this.$set(this,"data",obj);
},
remove(store, data) {
store.remove(data);
let obj = this.testFunc();
this.$set(this,"data",obj);
},
用了比较耗性能的方法:深层遍历
append (store, data, newNode) {
// 当前结点id
let currentId = data.id
// 深拷贝treeData
let _treeData = JSON.parse(JSON.stringify(this.treeData))
// 遍历树结点
_treeData.map(function map (item) {
let children = item.children = item.children || []
if (+item.id === +currentId) {
item.children.push(newNode)
} else {
item.children = children.map((child) => {
return map(child)
})
}
return item
})
// 替换整个树
this.treeData = _treeData
}
remove (store, data) {
let currentId = data.id
let _treeData = JSON.parse(JSON.stringify(this.treeData))
_treeData.map(function map (item) {
let children = item.children || []
let matchIndex = 0
let childMatched = children.some((child, childIndex) => {
if (+child.id === +currentId) {
matchIndex = childIndex
return true
}
})
if (childMatched) {
item.children.splice(matchIndex, 1)
} else {
item.children = children.map((child) => {
return map(child)
})
}
return item
})
this.treeData = _treeData
}
ElementUI 1.3.7
依然存在这个问题,我的解决办法是直接操作数据源对象,数据源的变化能够反应到树上。
怎么官方都没解答一下。。。我觉得这个问题很常见的啊
希望官方赶紧解决啊,这个问题折腾人好久了
apend(store, data)这个连球说明都没
tree操作确实有这一块的问题 数组怎么增加 不通过请求数据的办法
我也是直接通过修改数据源实现,就不用它例子中store的append方法了
同求
由于 Vue 2.0 里没有双向绑定,所以作为子组件的 Tree 是无法直接改变父组件的数据的。1.x 文档上的例子写得不好,请参考 2.0 文档上的这个例子:http://element-cn.eleme.io/#/zh-CN/component/tree#zi-ding-yi-jie-dian-nei-rong ,这段代码可以用在 1.x 版本中。
直接操作数据源,插入操作会视图会刷新,但是做删除操作视图就没反应了。折腾两天了.......
直接操作数据源,插入操作会视图会刷新,但是做删除操作视图就没反应了。折腾两天了.......
我今天也遇到这样,数据源新增后会自动在tree上显示,但数据源移除一个元素后tree上还有。
直接操作数据源,插入操作会视图会刷新,但是做删除操作视图就没反应了。折腾两天了.......
我今天也遇到这样,数据源新增后会自动在tree上显示,但数据源移除一个元素后tree上还有。
不知道你们解决了吗,我后来是发现删除时,除了移除node.data.children里对应的data,还要移除node.childNodes里对应的node。另外调用官方的remove方法,好像没什么反应。
神奇的是如果直接修改node.data里的数据,比如里面有一条name,name绑定到tree的显示名称上,改了这个值显示会跟着变,符合vue的响应机制。但改data里的children数组,比如置空,并不会触发响应,改childNodes才会
Most helpful comment
由于 Vue 2.0 里没有双向绑定,所以作为子组件的 Tree 是无法直接改变父组件的数据的。1.x 文档上的例子写得不好,请参考 2.0 文档上的这个例子:http://element-cn.eleme.io/#/zh-CN/component/tree#zi-ding-yi-jie-dian-nei-rong ,这段代码可以用在 1.x 版本中。