首页 > 解决方案 > ExtJS 4.1 树形面板 - 扩展树形面板会导致重复记录

问题描述

我正在使用 ExtJS 4.1。我有一个 TreePanel,我绑定到两个 TreeStore 之一。在我重新绑定商店并展开折叠节点后,记录变得重复并且我看到错误Uncaught TypeError: Cannot read property 'internalId' of undefined

另一个问题是,我只能绑定一次商店。当我第二次调用 treePanel.setRootNode() 时它不起作用(无论我是否扩展节点)。

看看这个小提琴

这是代码:

var sportsStore = Ext.create('Ext.data.TreeStore', {
  root: {
    expanded: true,
    id: 133,
    children: [{
        text: "Audi",
        id: 1,
        leaf: true
      },
      {
        text: "sports cars",
        expanded: true,
        id: 2,
        children: [{
            id: 3,
            text: "Porsche",
            leaf: true
          },
          {
            text: "Mustang",
            id: 4,
            leaf: true
          }
        ]
      },
      {
        text: "Jaguar",
        id: 5,
        leaf: true
      }
    ]
  }
});


var carStore = Ext.create('Ext.data.TreeStore', {
  root: {
    expanded: true,
    id: 1444,
    children: [{
        id: 6,
        text: "Toyota",
        leaf: true
      },
      {
        text: "cars",
        id: 7,
        expanded: true,
        children: [{
            id: 8,
            text: "honda",
            leaf: true
          },
          {
            text: "Nissan",
            id: 9,
            leaf: true
          }
        ]
      },
      {
        text: "Kia",
        id: 10,
        leaf: true
      }
    ]
  }
});



Ext.create('Ext.panel.Panel', {
  title: 'Car Simple Tree',
  width: 300,
  height: 450,

  renderTo: Ext.getBody(),

  items: [{
      xtype: 'button',
      text: 'sports',
      handler: function() {
        alert('You clicked the sports button!');
        var t = Ext.getCmp('tp');

        t.setRootNode(sportsStore.getRootNode());
      }
    },

    {
      xtype: 'button',
      text: 'car',
      handler: function() {
        alert('You clicked the car button!');
        var t = Ext.getCmp('tp');

        t.setRootNode(carStore.getRootNode());
      }
    },
    {

      xtype: 'treepanel',
      id: 'tp',
      store: sportsStore,
      rootVisible: false,
      lines: true
    }
  ]


});

标签: extjsextjs4extjs4.1

解决方案


只是为了记录,您知道您的问题在 6.0 中的一行中解决了,只需调用setStore()并作为参数传递您想要的商店,对吗?

这是在 6.0 中工作的演示

我玩了很长时间,虽然我的煎茶有点生锈(过去曾经是我的忠实粉丝),但我还是设法让一些东西正常工作。

现在它可能不是您的一杯茶,但它完全符合您的要求......您更改商店和扩展/折叠作品等。trick我在每次商店更改时动态重新创建树并将商店设置为默认值存储到那棵新树上。decommissioned树木被Ext.destroy等移除。

这是 Fiddle 中的 Ext 4.1 工作示例

这是供您参考的代码:

Ext.define('Thing', {
  extend: 'Ext.data.Model',
  fields: [{
    name: 'id',
    type: 'int'
  }, {
    name: 'text',
    type: 'string'
  }]
});

var sportsStore = Ext.create('Ext.data.TreeStore', {
  model: 'Thing',
  storeId: 'sportsStore',
  clearOnLoad: true,
  root: {
    expanded: true,
    id: 133,
    children: [{
      text: "Audi",
      id: 1,
      leaf: true
    }, {
      text: "sports cars",
      expanded: true,
      id: 2,
      children: [{
        id: 3,
        text: "Porsche",
        leaf: true
      }, {
        text: "Mustang",
        id: 4,
        leaf: true
      }]
    }, {
      text: "Jaguar",
      id: 5,
      leaf: true
    }]
  }
});
var carStore = Ext.create('Ext.data.TreeStore', {
  model: 'Thing',
  storeId: 'carStore',
  clearOnLoad: true,
  root: {
    expanded: true,
    id: 1444,
    children: [{
      id: 6,
      text: "Toyota",
      leaf: true
    }, {
      text: "cars",
      id: 7,
      expanded: true,
      children: [{
        id: 8,
        text: "honda",
        leaf: true
      }, {
        text: "Nissan",
        id: 9,
        leaf: true
      }]
    }, {
      text: "Kia",
      id: 10,
      leaf: true
    }]
  }
});
// This function does the magic by removing/then destroying the old tree and 
// adding the newly created one with default new store setup
function setupTree(storeName) {
  var pnl = Ext.getCmp('pnl');
  var treePanel = Ext.getCmp('tp')
  if (treePanel) {
    pnl.remove(treePanel)
    Ext.destroy(treePanel)
  }
  pnl.add(new Ext.create('Ext.tree.Panel', {
    id: 'tp',
    autoRender: true,
    rootVisible: false,
    store: storeName,
    animate: false,
    lines: true
  }))
}

Ext.create('Ext.panel.Panel', {
  id: 'pnl',
  title: 'Car Simple Tree',
  width: 300,
  height: 450,
  renderTo: Ext.getBody('#canvas'),
  items: [{
    xtype: 'button',
    text: 'sports',
    handler: function() {
      setupTree('sportsStore')
    }
  }, {
    xtype: 'button',
    text: 'car',
    handler: function() {
      setupTree('carStore')
    }
  }],
  listeners: {
    afterrender: function(self) {
      setupTree('sportsStore')
    }
  }
});

我还添加ids了存储以及为model商店定义了一个只是为了更接近best practices等。

做出这一举动的原因是setupTree查找具有特定 id 的树的函数,如果它找到它cleans it,然后创建一个新的具有默认存储的新存储,即我们单击的存储。

希望这可以帮助。


推荐阅读