EXTJS7 treestore.fillNode 追加多个节点时报错
版本
7.x
现象
使用treestore.fillNode(node,newNodes)接口向树节点追加孩子节点,如果newNodes数组元素是js对象而非Model对象,数组有多个元素时会报错
TypeError: Cannot read property ‘index’ of undefined
如果newNodes数组只有一个元素时则不会报错
解决
先使用NodeInterface.createNode接口将js对象转为Model对象
for(i = 0; i < newNodes.length; i++){
newNodes[i] = node.createNode(newNodes[i]);
}
treestore.fillNode(node, newNodes);
源码解析
- ext-core/src/data/TreeStore.js
fillNode: function(node, newNodes) {
var me = this,
newNodeCount = newNodes ? newNodes.length : 0;
// If we're filling, increment the counter so nodes can react without doing
// expensive operations
if (++me.bulkUpdate === 1) {
me.suspendEvent('datachanged');
}
if (newNodeCount) {
me.setupNodes(newNodes);
node.appendChild(newNodes, undefined, true);
}
// only set loaded if there are no newNodes;
// appendChild already handles updating the loaded status,
// and will do it *after* the child nodes have been added
else {
if (me.bulkUpdate === 1) {
node.set('loaded', true);
}
else {
node.data.loaded = true;
}
}
if (!--me.bulkUpdate) {
me.resumeEvent('datachanged');
}
// No need to call registerNode here, because each child will register itself as it joins
return newNodes;
},
setupNodes: function(newNodes) {
var me = this,
sorters = me.getSorters(),
needsIndexSort = false,
newNodeCount = newNodes.length,
/* eslint-disable-next-line max-len */
performLocalSort = me.sortOnLoad && newNodeCount > 1 && !me.getRemoteSort() && me.getFolderSort() || sorters.length,
performLocalFilter = me.needsLocalFilter(),
node1, node2, i;
// Apply any local filter to the nodes as we fill
if (performLocalFilter) {
me.doFilter(newNodes[0]);
}
// See if there are any differing index values in the new nodes. If not, then we do not
// have to sortByIndex
// 如果传入的记录元素数量大于1会执行此逻辑进行排序
for (i = 1; i < newNodeCount; i++) {
node1 = newNodes[i];
node2 = newNodes[i - 1];
// Apply any filter to the nodes as we fill
if (performLocalFilter) {
me.doFilter(node1);
}
// 此处根据传入的记录判断排序,但是传入的js对象并不一定有data字段,则抛出异常,如果使用Model数组则无此问题
needsIndexSort = node1.data.index !== node2.data.index;
}
// If there is a set of local sorters defined.
if (performLocalSort) {
// If sorting by index is needed, sort by index first
me.needsIndexSort = true;
Ext.Array.sort(newNodes, me.getSortFn());
me.needsIndexSort = false;
}
else if (needsIndexSort) {
Ext.Array.sort(newNodes, me.sortByIndex);
}
},
- ext-core/src/NodeInterface.js`
appendChild: function(node, suppressEvents, commit) {
if (Ext.isArray(node)) {
ln = node.length;
result = new Array(ln);
// Suspend view updating and data syncing during update
me.callTreeStore('beginFill');
for (i = 0; i < ln; i++) {
result[i] = me.appendChild(node[i], suppressEvents, commit);
}
// Resume view updating and data syncing after appending all new children.
// This will fire the add event to any views (if its the top level append)
me.callTreeStore('endFill', [result]);
}
else {
// Make sure it is a record 此处将js对象转换为Model
node = me.createNode(node);