如何将侦听器添加到 itemTpl 中定义的组件?

How to add listeners to components that are defined within itemTpl?

如何将侦听器添加到 itemTpl 中定义的组件?例如,如果我有一个绑定到商店的数据视图 (Ext.view.View),并且我定义了包含按钮和图像的 itempTpl,例如:

itemTpl: ['<div class="card" style="padding-left: 32px;">',
'<div><button type="button" class="btn"><span>Button</span></button></div>',
'<div class="img"><img src="https://www.w3schools.com/css/paris.jpg"></div>',                
'</div>']

如何检测按钮或项目的图像被单击?我知道如何向项目添加侦听器,但我想检测项目的某些内部 div 或 span 元素上的点击事件。

此外,我发现用 html 编写这些模板非常困难。据称 extjs 框架的主要优点之一是对开发人员完全隐藏 html 部分。所以,我想知道是否有更好的方法来使用数据视图显示这些信息,例如将面板或容器组件作为数据视图项包含在内。

您可以使用元素委托:

Ext.application({
    name: 'Fiddle',

    launch: function () {
        Ext.define('Image', {
            extend: 'Ext.data.Model',
            fields: [{
                name: 'src',
                type: 'string'
            }, {
                name: 'caption',
                type: 'string'
            }]
        });

        Ext.create('Ext.data.Store', {
            id: 'imagesStore',
            model: 'Image',
            data: [{
                src: 'http://www.sencha.com/img/20110215-feat-drawing.png',
                caption: 'Drawing & Charts'
            }, {
                src: 'http://www.sencha.com/img/20110215-feat-data.png',
                caption: 'Advanced Data'
            }, {
                src: 'http://www.sencha.com/img/20110215-feat-html5.png',
                caption: 'Overhauled Theme'
            }, {
                src: 'http://www.sencha.com/img/20110215-feat-perf.png',
                caption: 'Performance Tuned'
            }]
        });

        Ext.create('Ext.view.View', {
            store: Ext.data.StoreManager.lookup('imagesStore'),
            itemTpl: new Ext.XTemplate(
                '<div class="card" style="padding-left: 32px;">',
                '<div><button type="button" class="btn"><span class="btnSpan">Button</span></button></div>',
                '<div class="img"><img src="https://www.w3schools.com/css/paris.jpg" class="imgClass"></div>',
                '</div>',
            ),
            itemSelector: 'div.card',
            emptyText: 'No images available',
            listeners: {
                itemClick: function (view, record, item, index, e, eOpts) {
                    console.log(e.target);
                    const classList = e.target.classList;
                    if (classList.contains('btn')) {
                        console.log('btn is clicked');
                    } else if (classList.contains('btnSpan')) {
                        console.log('Span in Button is clicked');
                    } else if (classList.contains('imgClass')) {
                        console.log('ImgClass is clicked');
                    }
                }
            },
            renderTo: Ext.getBody(),
        });
    }
});