简体   繁体   English

Ext Js将父容器中的事件处理程序附加到其子项

[英]Ext Js Attach Event Handler In Parent Container To Its Child Item

A component definition: 组件定义:

Ext.define('Retroplanner.view.dimension.DimensionMapping', {
    alias: 'widget.dimensionMapping',
    extend: 'Ext.form.Panel',
    ...
    items: [{
       xtype: 'combo'
    }, ...
    ]

A ' select ' handler of the child item must create a widget and add this widget to the items array of its parent. 子项的“ select ”处理程序必须创建一个小部件并将该小部件添加到其父items数组中。

Inside of this child item, it its 'select' handler, I can find its parent by some search techniques. 在此子项中,它是其“选择”处理程序,我可以通过一些搜索技术找到其父项。 But I would like to avoid it if it is possible. 但我想避免这种情况。 I do not have a reference variable to the parent neither. 我也没有父母的引用变量。

A better approach would be - to create function in the parent, and attach it somehow to the child item: 更好的方法是-在父项中创建函数,然后以某种方式将其附加到子项:

Ext.define('Retroplanner.view.dimension.DimensionMapping', {
    ...
    onSiRemoteCombo: function(cmb, rec, idx) {
         alert("select handler");
         var newItem = Ext.widget('somexType');
         this.items.add(newItem);
    }

The question, how to attach onSiRemoteCombo ? 问题是,如何附加onSiRemoteCombo

I've found a similar solution here: How to create listener for child component's custom event 我在这里找到了类似的解决方案: 如何为子组件的自定义事件创建侦听器

First, it does not work for me. 首先,它对我不起作用。 I can give a full example that I tried to use. 我可以举一个我尝试使用的完整示例。 2nd, I would like to create items via the most common way/in the common place, not via initComponent method. 第二,我想通过最普通的方式/在普通的地方创建项目,而不是通过initComponent方法。 I would like to have something like: 我想要类似的东西:

Ext.define('Retroplanner.view.dimension.DimensionMapping', {
...
afterRender: function() {
    var me = this;
    //exception here
    //Uncaught TypeError: Cannot read property 'on' of undefined
    me.items[0].on('select', onSiRemoteCombo, this);
},

items: [{
       xtype: 'combo'
   }, ...
],

onSiRemoteCombo: function(cmb, rec, idx) {
     alert("Ttt");
     var dimensionMapping = Ext.widget('propGrid');
     this.getParent().add(dimensionMapping);
}

But I get an exception: 但我有一个例外:

//exception here
//Uncaught TypeError: Cannot read property 'on' of undefined
me.items[0].on('select', onSiRemoteCombo, this);

And also, attach a listener after each rendering, really is a bad idea. 而且,在每个渲染之后都添加一个侦听器,确实是一个坏主意。

Are there any best practices for such use cases? 是否有针对此类用例的最佳实践? Ideally, if it will work in different versions of Ext JS, at least in 5.x and 6.x 理想情况下,如果它可以在不同版本的Ext JS中运行,至少在5.x和6.x中都可以

Attach a handler in a child and access its parent? 在孩子中附加处理程序并访问其父级? A child should not depend on its parent. 孩子不应该依赖父母。 Only parent should know, what to do. 只有父母应该知道该怎么办。

One way to solve this is by wrapping the combo item component initialization into form's initComponent method. 解决此问题的一种方法是将组合项目组件的初始化包装到窗体的initComponent方法中。 This way when setting a listener for the combo, you can use this.formMethod to reference a form method. 这样,在为组合设置侦听器时,可以使用this.formMethod引用表单方法。 Here is some code: 这是一些代码:

Ext.define('Fiddle.view.FirstForm', {
    extend: 'Ext.form.Panel',
    bodyPadding: 15,

    initComponent: function () {
        Ext.apply(this, {
            items: [{
                xtype: 'combo',
                fieldLabel: 'First Combo',
                store: ['first', 'second'],
                listeners: {
                    'select': this.onComboSelect
                }
            }]
        });

        this.callParent();
    },

    onComboSelect: function () {
        alert('I am a first form method');
    }
});

The second approach by using a string listener on the combo, and by setting defaultListenerScope to true on the form. 第二种方法是在组合上使用字符串侦听器,并在窗体上将defaultListenerScope设置为true。 This way the listener function will be resolved to the form's method. 这样,侦听器功能将解析为表单的方法。 Again, some code: 再次,一些代码:

Ext.define('Fiddle.view.SecondForm', {
    extend: 'Ext.form.Panel',
    bodyPadding: 15,
    defaultListenerScope: true,

    items: [{
        xtype: 'combo',
        fieldLabel: 'Second Combo',
        store: ['first', 'second'],
        listeners: {
            'select': 'onComboSelect'
        }
    }],

    onComboSelect: function () {
        alert('I am a second form method');
    }
});

And here is a working fiddle with both approaches: https://fiddle.sencha.com/#view/editor&fiddle/27un 这是两种方法的有效提琴: https : //fiddle.sencha.com/#view/editor&fiddle/27un

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM