【问题标题】:Best way to customize the structure of an Extjs 4+ field自定义 Extjs 4+ 字段结构的最佳方式
【发布时间】:2013-03-21 18:40:56
【问题描述】:

我对自定义 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 中对我来说是不可能的。

感谢您的任何帮助或建议。

【问题讨论】:

  • 您要问的内容有点令人困惑。您想要您创建的按钮的 HTML 吗?如果是这种情况,请使用button.getEl().getHTML()
  • 将它包装在容器中是最好的解决方案,你能详细说明为什么它不可能吗?
  • @Evan Trimboli 该字段需要保留Extjs字段api。如果我们不必全部重新实现它会更好。
  • @VarunAchar 在调用“getSubTplData”时,未呈现按钮元素,因此 getEl() 返回未定义。也许这不是这样做的方法......?是否有与从 Trigger 扩展完全不同的方法来实现此字段结构?
  • 如果你看一下form.field.Field mixin,实际上并没有太多的实现,你基本上只需将这些调用级联到实际的字段。

标签: javascript extjs field custom-component


【解决方案1】:

它的性能不是很好,但可以使用 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)
    }
});

【讨论】:

  • 嘿,谢谢你的例子。它确实让我对如何做到这一点有了一些了解,但是我注意到您使用的是仅在 Extjs 4.1.3+ 中可用的 button.render(..) ,我需要在 4.0.7 上使用它。抱歉,我没有提到主要限制:p。我偏离了我原来的想法吗?我不应该能够将默认按钮标记分配给 getSubTplData 中的“buttonEl”属性吗?我只是不确定在哪里可以找到默认的 Extjs 按钮标记...
  • 我不确定为什么 4.* 渲染的文档不同,但 Ext.Component.render 自 Ext 1 以来就存在。docs.sencha.com/ext-js/3-4/#!/api/Ext.Component-method-render 。 4.* 中的每个组件都有一个渲染方法。您甚至可以在他们的示例中看到它被使用。 ext-4.0.7/examples/themes/themes.js
  • 啊.. 抱歉,我确实在 AbstractComponent 中看到了它,但是它被标记为私有。如果可能的话,我绝对想避免使用私有函数。
  • 我只会使用渲染,它已在 Ext 1,2 和 3 中公开可用,并且仍然存在于 4.* 您可以使用 renderTo 配置获得相同的行为,但顺序如何创造的东西必须改变才能让它发挥作用。 renderrenderTo 更灵活,这就是我使用它的原因。 docs.sencha.com/ext-js/4-1/#!/api/… 这实际上在文档中:When using this config, a call to render() is not required.
  • 好的,谢谢。出于我个人的理智,我最初的建议是否可能使用“fieldSubTpl”和“getSubTplData”?你能对此发表评论吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-14
  • 1970-01-01
相关资源
最近更新 更多