【问题标题】:Extjs 5.1.2 Listeners on a dynamically generated elementExtjs 5.1.2 动态生成元素上的监听器
【发布时间】:2016-11-04 20:26:23
【问题描述】:

我正在创建一个将动态生成折叠面板的页面。当用户展开这些面板时,它将执行 GET 请求并使用 JSON 响应填充此生成的面板。这个想法是执行一种延迟加载或按需加载,因为最初显示的数据量可能会变得不堪重负。

但是,我似乎无法让我的面板的侦听器正常工作。

代码如下,通过按钮的点击函数生成面板:

          xtype : 'button',
          listeners : {
            click : function (button, e, eOpts) {
              console.log("Click function");
              Ext.Ajax.request({
                url: 'data/Countries.json',
                success: function(response, options) {
                  var data = Ext.JSON.decode(response.responseText).results;
                  var container = Ext.getCmp('panelContainer');
                  container.removeAll();
                  for (i = 0; i < data.length; i++)
                  {
                    container.add({
                      xtype: 'panel',
                      title: 'Country Name - ' + data[i].countryName,
                      collapsible: true,
                      listeners: {
                        expand: function() {
                          Ext.Ajax.request({
                            url: 'data/CountryData.json',
                            success: function(response, options) {
                              var data = Ext.JSON.decode(response.responseText).results;
                              var me = this;
                              me.add({
                                xtype: 'grid', 
                                store: Ext.create('Ext.data.Store',
                                  {
                                      fields : [{
                                        name: 'gdp'
                                      }, {
                                        name: 'rank'
                                      }, {
                                        name: 'founded'
                                      }, {
                                        name: 'governor'
                                      }, {
                                        name: 'notes'
                                      }], //eo fields
                                    data: data.information,
                                  }),// eo store
                                columns: [
                                  { text: 'GDP',  dataIndex: 'gdp'},
                                  { text: 'rank', dataIndex: 'rank'},
                                  { text: 'Date', dataIndex: 'founded'},
                                  { text: 'name', dataIndex: 'governor'},
                                  { text: 'Notes', dataIndex: 'notes', flex: 1, cellWrap: true}
                                ], //eo columns
                                autoLoad: true
                              });

                            },
                            failure: function(response, options) {}
                          });
                        },
                        collapse: function() {
                          console.log("Collapse function");
                          var me = this;
                          me.removeAll();
                        }
                      }//eo panel listeners
                    });//eo cont.add() 
                  }//eo for loop
                }, //eo success
                failure: function(response,  options) {
                  //HTTP GET request failure
                }//eo failure
              });//eo Ajax request
            } //eo click
          }//eo button listeners

最初,面板是通过单击事件动态生成的以及填充的网格,效果很好。通过将网格创建包装在动态生成的面板上的侦听器中以创​​建按需加载,我无法触发展开或折叠侦听器。

四处搜索,我没有尝试过的一种可能的解决方案是创建一个自定义组件并通过其 xtype 调用它,而不是内联构建所有内容,这将让我在那里定义侦听器而不是将它们嵌套在一个函数中(这个对于可读和可重用的代码也更好,但我现在只是试图找到问题的根源)。

动态生成的面板上的侦听器是否存在问题?折叠和展开的事件触发器没有触发的原因是什么?

感谢大家的帮助!

【问题讨论】:

  • 我刚刚将container.add() 中的面板移动到它自己的组件中,并通过xtype 调用它。我能够触发扩展功能,但我不确定如何获取侦听器的组件(我只是猜测var me=this; me.add())。另外,奇怪的是,我用作容器的外面板突然塌陷并带有标题,所以我也必须调查一下。
  • Offtopic:我建议您将侦听器函数与视图分开,或者至少使用 listenerScope 将其写入项目定义下。该商店也可以在整个类下或不同的文件中定义,只需按名称等调用。因为它看起来像意大利面条代码。为听众检查这个小提琴fiddle.sencha.com/#fiddle/1brb
  • 当然,我一定要把它们分开;我才刚刚开始,所以我不太确定如何在不同的文件中设置存储并通过网格配置将不同的数据集传递给它,或者如何正确使用监听器;我敢肯定它比我想象的要简单。我看到您的侦听器功能正确触发,我的侦听器没有触发是否有原因?我需要使用 listenerScope 吗?我会继续测试。谢谢!

标签: extjs extjs5


【解决方案1】:

我还有一些问题,但由于我的主要问题是关于解雇听众,我会写下我找到的解决方案。

我遇到的问题是让侦听器在动态生成的元素中触发。这导致嵌套的侦听器函数,并且我没有定义范围。我曾尝试过 pagep 设置 defaultListenerScope 的解决方案,但对我个人而言,我没有看到任何变化。

我改为将侦听器函数包装到它们自己的函数中,然后通过侦听器调用,如下所示:

listeners: {
    expand: 'expandFunction',
    collapse: 'collapseFunction'
},//eo panel listeners

expandFunction: function() {
    //Do Ajax request and add grid to panel
},
collapseFunction: function() {
    //Remove all child elements from this panel
}

不要这样做:

listeners: {
    expand: function() {
        //Do Ajax request and add grid to panel
    },
    collapse: function() {
        //Remove all child elements from this panel
    }
},//eo panel listeners

通过以这种方式包装信息,我能够(在一定程度上)移除带有生成元素的侦听器的嵌套。我还创建了一个自定义组件,并将这些侦听器与我正在生成的组件放在一起。我现在唯一的问题是填充生成的元素,因为我在尝试引用组件的 itemId 时收到 Uncaught TypeError: Cannot read property 'add' of undefined

我的最终简化代码如下所示:在单击按钮时生成一个折叠面板,并在展开时使用生成的数据填充它:

//View.js
    click: function (button, e, eOpts) {
              Ext.Ajax.request({
                url: 'data/Countries.json',
                success: function(response, options) {
                  var data = Ext.JSON.decode(response.responseText).results;
                  var container = Ext.getCmp('panelContainer');
                  console.log(container);
                  container.removeAll();
                  for (i = 0; i < data.length; i++)
                  {
                    container.add({
                      xtype: 'customPanel',
                      title: data[i].country
                    });
                  }
                });

//customPanel.js
    Ext.define('MyApp.view.main.CustomPanel', {
    extend: 'Ext.panel.Panel',
    alias: 'widget.customPanel',

    xtype: 'panel',
    collapsible: true,
    collapsed: true,
    listeners: {
        expand: 'expandFunction',
        collapse: 'collapseFunction'
    },//eo panel listeners

    expandFunction: function() {
        //Do Ajax request and add grid to panel
    },
    collapseFunction: function() {
        //Remove all child elements from this panel
    }
});

【讨论】:

  • 我尝试这样使用时似乎还是有些挑剔,所以我会做更多的测试,看看问题的根本原因是什么。除非面板中有子元素,否则事件似乎仍然不会触发,这真的很奇怪。
猜你喜欢
  • 2011-10-12
  • 2012-12-24
  • 1970-01-01
  • 2019-10-21
  • 2012-01-22
  • 2022-01-17
  • 2021-03-17
  • 1970-01-01
  • 2022-01-05
相关资源
最近更新 更多