ExtJS 6.0.1 TreeView如何重复显示指定记录(作为收藏栏)
实现ExtJS TreeStore收藏节点同步到独立树面板的方案
嘿,这个需求我之前在ExtJS 6.0.1里落地过,核心思路是通过节点引用关联两个TreeStore,完全避免数据重复,同时监听favourite属性的变化来自动同步收藏树的内容。下面给你一步步拆解实现方式:
1. 核心设计思路
我们不需要复制节点数据,而是直接将主树中标记为收藏的节点引用到收藏树的根节点下。因为ExtJS的Model实例是引用类型,修改主树节点的favourite属性,收藏树里的对应节点会自动同步,反过来操作收藏树的节点也会同步回主树,完美解决数据重复问题。
2. 具体实现步骤
第一步:定义统一的Model
先确保主树和收藏树使用同一个Model,保证数据结构一致:
Ext.define('MyApp.model.TreeNode', { extend: 'Ext.data.Model', fields: [ 'text', {name: 'favourite', type: 'boolean', defaultValue: false} ] });
第二步:配置主TreeStore并添加监听
在主Store中监听节点的update事件,当favourite属性变化时,自动同步到收藏树:
const mainTreeStore = Ext.create('Ext.data.TreeStore', { model: 'MyApp.model.TreeNode', root: { text: '全部内容', expanded: true, children: [ {text: '项目文档', favourite: false}, {text: '常用工具', favourite: true}, // 更多初始节点... ] }, listeners: { update: function(store, record) { // 仅当favourite属性发生变化时触发同步 if (record.get('favourite') !== record.previousValues.favourite) { this.syncFavouriteNode(record); } }, // 自定义同步方法 syncFavouriteNode: function(record) { const favTree = Ext.getCmp('favouritesTreePanel'); const favRoot = favTree.getStore().getRootNode(); if (record.get('favourite')) { // 避免重复添加:检查节点是否已在收藏树中 if (!favRoot.contains(record)) { favRoot.appendChild(record); } } else { // 取消收藏时从收藏树移除节点 if (favRoot.contains(record)) { record.remove(); } } } } });
第三步:配置收藏TreeStore和TreePanel
初始化收藏树时,自动把主树中已标记为收藏的节点加进去,同时绑定到独立的TreePanel:
// 初始化收藏Store,自动加载主树中已收藏的节点 const favouritesStore = Ext.create('Ext.data.TreeStore', { model: 'MyApp.model.TreeNode', root: { text: '我的收藏', expanded: true, children: mainTreeStore.getRootNode().queryBy(node => node.get('favourite')).getRange() } }); // 创建收藏树面板 Ext.create('Ext.tree.Panel', { id: 'favouritesTreePanel', title: '我的收藏', store: favouritesStore, width: 300, columns: [ {xtype: 'treecolumn', dataIndex: 'text', flex: 1}, // 可选:保留收藏切换图标,操作会同步回主树 { xtype: 'actioncolumn', items: [{ icon: 'resources/icons/unfav.png', getClass: function(v, meta, rec) { return rec.get('favourite') ? 'fav-icon' : 'unfav-icon'; }, handler: function(grid, rowIndex) { const record = grid.getStore().getAt(rowIndex); record.set('favourite', !record.get('favourite')); } }] } ] });
第四步:额外优化点
- 远程数据加载同步:如果主树是从远程加载数据,要在主Store的
load事件里重新同步收藏树,确保新加载的已收藏节点被加入收藏树。 - 收藏树排序:可以给收藏Store添加排序规则,比如按节点名称或者收藏时间排序:
favouritesStore.sort('text', 'ASC'); - 保护根节点:设置收藏树的根节点为不可选择、不可编辑,避免误操作删除根节点:
root: { text: '我的收藏', expanded: true, selectable: false, editable: false }
效果验证
- 当你在主树中点击actioncolumn图标标记为收藏时,该节点会自动出现在收藏树的"我的收藏"节点下;
- 取消收藏时,节点会从收藏树中移除;
- 无论操作主树还是收藏树的节点,两边的
favourite状态都会实时同步,且完全没有数据重复。
内容的提问来源于stack exchange,提问作者trouserboycott
相关产品推荐
相关产品推荐

