1

我对自定义 Extjs 触发字段很感兴趣,我想知道执行以下操作的最佳方法是什么(请原谅文本图)(方括号代表元素):

[field label] [trigger element] [button]

它基本上是一个触发器字段,其末尾附加了一个小按钮。我希望只是扩展触发字段,并可能通过 fieldSubTpl 添加按钮,即:

fieldSubTpl: [
    '<input id="{id}" type="{type}" ',
        '<tpl if="name">name="{name}" </tpl>',
        '<tpl if="size">size="{size}" </tpl>',
        '<tpl if="tabIdx">tabIndex="{tabIdx}" </tpl>',
        'class="{fieldCls} {typeCls}" autocomplete="off" />',
    '<div id="{cmpId}-triggerWrap" class="{triggerWrapCls}" role="presentation">',
        '{triggerEl}',
        '{buttonEl}',  <--- New Button Element
        '<div class="{clearCls}" role="presentation"></div>',
    '</div>',
    {
        compiled: true,
        disableFormats: true
    }
]

我现在希望能够在字段的构造函数中创建一个 Ext.Button,并以某种方式将它用于 {buttonEl}。完整示例:

Ext.define("Ext.ux.NewField", {
    extend: "Ext.form.field.Trigger",

    constructor: function(config) {
        config.newButton = Ext.create("Ext.button.Button", {
            /** ... button configs ... **/
        });

        Ext.applyIf(config, {
            fieldSubTpl: // as shown above
        });

        this.callParent([config]);
    },

    initComponent: function() {
        this.callParent();

        this.newButton.on("click", this.__onButtonClick, this);
    },

    getSubTplData: function() {
        var obj = this.callParent(arguments);
        obj.buttonEl = this.newButton.???????  <-- This is what I can't figure out
        return obj;
    },

    __onButtonClick: function() {
        // ...
    } 
});

我将如何应用默认的 Ext 按钮配置以及我在按钮构造函数中覆盖的那些?这甚至可能还是我在这里使用模板完全错误?

同样,我想保持 Ext 字段的“is-a”关系,因此仅将触发器字段和按钮包装在 Ext.container.Container 中对我来说是不可能的。

感谢您提供任何帮助或建议。

4

1 回答 1

0

它的性能不是很好,但可以使用 childEls 和/或渲染选择器。

    Ext.define("Ext.ux.NewField", {
    extend: "Ext.form.field.Trigger",

    fieldSubTpl: [
        '<input id="{id}" type="{type}" ',
            '<tpl if="name">name="{name}" </tpl>',
            '<tpl if="size">size="{size}" </tpl>',
            '<tpl if="tabIdx">tabIndex="{tabIdx}" </tpl>',
            'class="{fieldCls} {typeCls}" autocomplete="off" />',
        '<div id="{cmpId}-triggerWrap" class="{triggerWrapCls}" role="presentation">',
            '{triggerEl}',
            '<div class= "myButton"> </div>',  
            '<div class="{clearCls}" role="presentation"></div>',
        '</div>',
        {
            compiled: true,
            disableFormats: true
        }
    ],

    initComponent: function() {
        this.renderSelectors = {
            buttonEl: '.myButton'
        };
        this.newButton = new Ext.button.Button({
            text: 'New'
        });
        this.on('afterrender', function() {
            this.newButton.render(this.buttonEl);
        }, this);

        this.newButton.on("click", this.__onButtonClick, this);

        this.callParent();
    },

    __onButtonClick: function() {
        window.alert("new")
    } 
});

这实际上会在输入 el 下方呈现按钮,因此需要调整模板,但按钮是字段的一部分并呈现在其元素内部。renderSelector 基本上是在渲染时找到与我的“.myButton”匹配的元素,然后将 this.buttonEl 设置为关联的 Ext.Element。afterrender 侦听器只是向该元素呈现一个按钮。渲染和重新渲染主要是对性能的否定,但它比拥有应该像字段一样运行的容器的开销或在渲染模板内编写按钮的标记要容易得多。

编辑以回应评论:

getSubTplData 旨在收集 XTemplate 在应用其值时将使用的数据。如果你这样做了,你的例子{buttonEl}将被替换为[object Object]. 如果你做了类似的事情obj.buttonEl = this.newButton.id,它将{buttonEl}用按钮的 id 替换,但这没有用。您的示例不起作用,因为您的模板没有为要渲染的按钮提供挂钩,并且您与按钮的渲染getSubTplData无关。

在不弄乱渲染模板的情况下,您可以执行类似这样的操作来渲染触发字段下方的按钮。

Ext.define('CustomTrigger', {
    extend: 'Ext.form.field.Trigger',
    initComponent: function() {
        this.callParent();
        this.btn = new Ext.Button({text: 'My Trigger'});
        this.on('afterrender', function(){
            this.btn.render(this.el.createChild());
        }, this)
    }
});
于 2013-03-22T22:11:39.630 回答