EXTJS7 treestore.fillNode 追加多个节点时报错

小编:管理员 496阅读 2022.09.07

版本

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);
复制
关联标签: