带有可单击按钮的组合框列表

时间:2018-07-12 08:41:17

标签: extjs extjs6-classic

我正在尝试创建一个带有可单击按钮的下拉菜单的组合框。

我已覆盖renderTpl,并复制了今天的日期选择器的按钮实例化代码。 This fiddle shows what I have now,按钮已呈现但仍不可单击,处理程序未执行。

我想念什么?

代码:

Ext.define('EnhancedCombo', {
    extend: 'Ext.form.field.ComboBox',
    xtype: 'enhancedcombo',
    footerButtonUI: 'default',
    selAllText: 'Select All',
    initComponent: function() {
        var me = this;
        me.callParent(arguments);
        me.selAllBtn = new Ext.button.Button({
            ui: me.footerButtonUI,
            ownerCt: me,
            ownerLayout: me.getComponentLayout(),
            text: me.selAllText,
            tabIndex: -1,
            ariaRole: 'presentation',
            handler: me.selectAll,
            scope: me
        });
    },
    listConfig: {
        renderTpl: [
            '<div id="{id}-listWrap" data-ref="listWrap"',
                    ' class="{baseCls}-list-ct ', Ext.dom.Element.unselectableCls, '">',
                '<ul id="{id}-listEl" data-ref="listEl" class="', Ext.baseCSSPrefix, 'list-plain"',
                    '<tpl foreach="ariaAttributes"> {$}="{.}"</tpl>',
                '>',
                '</ul>',
            '</div>',
            '<div id="{id}-footerEl" data-ref="footerEl" role="presentation" class="{baseCls}-footer" style="">{%this.renderSelAllBtn(values, out)%}</div>',
            {
                disableFormats: true,
                renderSelAllBtn: function(values, out) {
                    Ext.DomHelper.generateMarkup(values.$comp.ownerCmp.selAllBtn.getRenderTree(), out);
                }
            }
        ],
    },

    selectAll: function() {
        console.log('select all');
        this.getPicker().getSelectionModel().selectAll();
    }
});

2 个答案:

答案 0 :(得分:1)

当您使用Ext.DomHelper.generateMarkup()时,它将以Array的形式返回html。因此,您只是附加了该按钮的html而不是组件。

您可以实现此功能,需要像这样在picker上使用addListener方法

picker.addListener('afterrender', function(){},scop);

然后,在afterrender事件内部,您可以像这样通过使用Ext.dom.Element.down()获取dom元素来添加click事件

picker.addListener('afterrender', (comp) => comp.el.down('.selectall').on('click', this.selectAll, comp), me)

FIDDLE

在上面的小提琴中,我创建了一个演示。

代码片段

Ext.application({
    name: 'Fiddle',

    launch: function () {
        var btn = new Ext.button.Button({
            text: 'Working button',
            handler: function () {
                alert('Working button click');
            },
            listeners: {
                afterrender: function () {
                    console.log('afterrender Working button')
                }
            }
        });

        function getBtnHtml() {
            let button = new Ext.button.Button({
                text: 'No wokring button',
                handler: function () {
                    alert('Test 2');
                },
                listeners: {
                    afterrender: function () {
                        console.log('afterrender not Working button')
                    }
                }
            });
            return Ext.DomHelper.generateMarkup(button.getRenderTree(), []).join('')
        }

        Ext.create({
            xtype: 'panel',
            title: 'Demo',
            renderTo: Ext.getBody(),
            layout: 'hbox',
            defaults: {
                flex: 1,
                margin: 10
            },
            items: [btn, {
                xtype: 'panel',
                html: getBtnHtml()
            }]
        })

        Ext.define('EnhancedCombo', {
            extend: 'Ext.form.field.ComboBox',
            xtype: 'enhancedcombo',
            footerButtonUI: 'default',
            selAllText: 'Select All',
            multiSelect: true,
            initComponent: function () {
                this.callParent(arguments);

                var me = this,
                    picker = me.getPicker();

                me.selAllBtn = new Ext.button.Button({
                    ui: me.footerButtonUI,
                    ownerCt: me,
                    ownerLayout: picker.getComponentLayout(),
                    text: me.selAllText,
                    cls: 'selectall',
                    tabIndex: -1,
                    ariaRole: 'presentation',
                    scope: me
                });

                picker.addListener('afterrender', (comp) => comp.el.down('.selectall').on('click', this.selectAll, comp), me);

            },
            listConfig: {
                renderTpl: [
                    '<div id="{id}-listWrap" data-ref="listWrap"',
                    ' class="{baseCls}-list-ct ', Ext.dom.Element.unselectableCls, '">',
                    '<ul id="{id}-listEl" data-ref="listEl" class="', Ext.baseCSSPrefix, 'list-plain"',
                    '<tpl foreach="ariaAttributes"> {$}="{.}"</tpl>',
                    '>',
                    '</ul>',
                    '</div>',
                    '<div id="{id}-footerEl" data-ref="footerEl" role="presentation" class="{baseCls}-footer" style="">{%this.renderSelAllBtn(values, out)%}</div>', {
                        disableFormats: true,
                        renderSelAllBtn: function (values, out) {
                            Ext.DomHelper.generateMarkup(values.$comp.ownerCmp.selAllBtn.getRenderTree(), out);
                        }
                    }
                ],
            },

            selectAll: function () {
                console.log('select all');
                this.getSelectionModel().selectAll();
            }
        });

        Ext.create('EnhancedCombo', {
            renderTo: Ext.getBody(),
            store: ['Test 1', 'Test 2']
        }).expand();

    }
});

答案 1 :(得分:1)

每个组件都有方法finishRender,在渲染运行期间从父组件调用该方法。当我通过generateMarkup手动生成标记时,还必须在呈现选择器之后手动调用finishRender方法,然后才能单击按钮。

在DatePicker中,从覆盖的私有finishRenderChildren方法中调用todayBtn的finishRender。尽管我无法覆盖选择器的私有方法,但是可以从可以添加到选择器的finishRender侦听器中调用相同的afterrender方法(如Narendra Jadhav所建议的那样):

listConfig: {
    ...
    listeners: {
        afterrender: function(picker) {
            picker.ownerCmp.selAllBtn.finishRender();
        }
    }
},