【问题标题】:extjs treepanel weird behavior after click on + to expand单击 + 展开后 extjs treepanel 的奇怪行为
【发布时间】:2019-05-21 04:06:51
【问题描述】:

我正在构建一个树形面板,当我单击 + 图标展开节点或单击 - 折叠节点时,树会出现非常奇怪的行为,我的意思是:

selectitemdblclick 事件按预期工作。

另外,我附上了这些事件:

beforeitemexpand: function(item, eOpts) {
                   ...
                },
                beforeitemcollapse: function(item, eOpts) {
                    ...
                },
                beforeexpand: function(panel, animate, eOPts) {
                    ...
                },
                beforecollapse: function(panel, animate, eOPts) {
                    ...
                }

它们都不起作用。

这是我的树形面板视图代码:

Ext.define('mycomponent.mytreepanelview', {
    extend: 'Ext.window.Window',
    itemId: 'mytreewindow',
    id: 'mytreewindow',
    xtype: 'mytreewindow',
    modal: true,
    bodyPadding: 10,
    height: 450,
    width: 375,
    closeAction: 'destroy',
    resizable: false,
    items: [
        {
            xtype: 'label',
            text: '?????'
        },
        {
            id: 'mytree',
            xtype: 'treepanel',
            border: true,
            width: 345,
            height: 325,
            title: '',
            rootVisible: false,
            header: false,
            displayField: 'text',
            store: Ext.create('mycomponent.store', {}),
            viewConfig: {
                preserveScrollOnRefresh: true,
                toggleOnDblClick: false
            }
        },
        {
            xtype: 'label',
            text: '??????'
        }
    ],
    buttons: [
        {
            itemId: 'okButton',
            id: 'okButton',
            text: 'Ok'
        },
        {
            itemId: 'cancelButton',
            id: 'cancelButton',
            text: 'Cancel'
        }
    ],

    initComponent: function () {
        this.callParent(arguments);
        dtzerp.getController('mycomponent.mycontroller');
    },

    constructor: function (config) {
        this.callParent(arguments);
        this.initConfig(config);
        return this;
   }
});

另外,这是我的商店:

Ext.define('mycomponent.mystore', {
    extend: 'Ext.data.TreeStore',
    alias: 'store.mystore',
    storeId: 'mystore',
    model: Ext.create('mycomponent.mymodel'),
    restful: true,
    autoLoad: false,
    root: {
        text: 'Loading...',
        id: 'NULL',
        expanded: true,
        loaded: true
    },
    proxy: {
        type: 'ajax',
        headers: {
           'Accept': '*/*',
           'Cache-Control': 'no-cache',
           'Content-Type': 'application/json',
           'Authorization': localStorage.token
        },
        extraParams: {
           sort: 'name',
           'filter[active]': true,
           'filter[idparent][null]': 0
        },
        reader: {
            type: 'json',
            rootProperty: 'data',
            successProperty: 'success'
        },
        api: {
           read: 'http://myurl',
           create: 'http://myurl',
           update: 'http://myurl',
           destroy: 'http://myurl'
        }
    },
    constructor: function (config) {
        config = Ext.apply({
            rootProperty: Ext.clone(this.rootData)
        }, config);

        this.callParent([config]);
    }
});

另外,从rest api传来的数据总是一个数组,里面有选中节点的数据,也就是说只有选中节点的子节点,如果有的话。

在第一次调用时,rest api 将返回如下内容:

[
  {id: '1', name: 'One', text: 'Item one', leaf: false, idparent: null}, 
  {id: '2', name: 'Two', text: 'Item two', leaf: false, idparent: null}, 
  {id: '3', name: 'Three', text: 'Item three', leaf: true, idparent: null}
]

然后,如果我选择第一项,其余 api 将返回如下内容:

[
   {id: '4', name: 'Child 1-1', text: 'Child 1 of 1', leaf: false: idparent: '1'},
   {id: '5', name: 'Child 2-1', text: 'Child 2 of 1', leaf: true: idparent: '1'}
]

等等……

更新 我正在命令商店(Ext.data.TreeStore)加载包含树形面板的窗口的show 事件。这是在控制器中:

  init: function () {
            this.control({
               '#mytreewindow': {
                   show: function (item, eOPts) {
                     var store = Ext.getStore('mytreestore');
                     var children = [];
                     var that = this;

                     store.load({
                         callback: function (records) {
                             debugger;
                             console.log(records);

                             var children = [
                               {text: 'testing',
                                leaf: false,
                                idparent: null,
                                idelement: 1,
                                children: [{idparent: 1,
                                            text: 'testing child',
                                            idelement: 2,
                                            leaf: true,
                                            children: []
                               }
                             ];
                             store.loadData(children, false);
                         }

存储进入回调,但是当debugger 停止执行时,在执行回调之前,树被来自 rest-api 的数据填充。因此,在store.loadData(... 之后,树会使用新信息更新,但是,当单击节点 testing 中的节点 + 时,它会返回到与图像中相同的状态。

我是否缺少任何属性,或者我需要添加任何配置以避免这种奇怪的行为?

【问题讨论】:

  • 你能把例子附在小提琴上吗?商店里有什么数据?
  • @norbeq 存储数据来自一个 rest api,并且树是按需加载的
  • @norbeq 我已经更新了商店的问题
  • 我的意思是存储数据而不是存储定义。您需要附上示例(在小提琴上更好)来解释问题出在哪里并且可以重新创建。
  • 我刚刚更新了我的答案。您需要进行请求,并在回调中添加子节点并再次展开节点。查看刷新的示例

标签: extjs


【解决方案1】:

您需要在Ext.tree.Panel 中覆盖Ext.tree.View 中的onBeforeExpand 方法。

你可以这样做:

viewConfig: {
    onBeforeExpand: function (n) {
        if (n.childNodes.length === 0) {
            //HERE YOU MUST DO REQUEST AND IN CALLBACK:
            n.appendChild(twoItemNodes);
            n.expand();
            return false;
        }
    }
}

看小提琴的例子:https://fiddle.sencha.com/#view/editor&fiddle/2sbc

【讨论】:

  • 我不确定是否理解您的回复。商店加载完成后我有一个回调,我可以在其中将项目添加到所选节点中。我怎样才能把这个sn-p的代码放在那个回调中?我的意思是,在您的示例中,您告诉将加载方法和回调放在视图中,而不是在控制器中......有没有办法从控制器调用 viewConfig: { onBeforeExpand: ...
  • 为什么要从控制器call viewConfig...?当您创建新的视图实例时,您可以在控制器中设置 viewConfig。可以附上控制器代码和创建视图的代码吗?
  • 我不是从控制器调用 viewconfig,而是从视图调用。当数据来自restapi时,为什么树面板会做如此奇怪的事情?
  • 因为当您点击时 - 还没有数据。我不知道你的应用程序架构。你在哪里创建窗口mytreewindow?可以附上这段代码吗?
  • 我从控制器调用该窗口:在事件单击按钮时我设置:var treewin = Ext.create('mycomponent.mytreewindow'); 然后treewin.show();
猜你喜欢
  • 2013-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多