使用ExtJs编写自定义xtype脚本以在aem 6.2中开发多字段

时间:2016-10-08 06:11:34

标签: extjs aem

你好我是ExtJs脚本的新手,我试图开发自定义多字段,我能够理解节点创建部分,但在脚本部分我无法捕捉一些像监听器添加范围的东西:这个,fn:this.updatehidden 我试着谷歌答案,但我得到任何满意的答案。任何人都可以向我解释范围:这个部分 以及为什么我们在initcomponent中调用超类构造函数,也欢迎任何相关资源

提前致谢 喜欢编码

Ejst.CustomWidget = CQ.Ext.extend(CQ.form.CompositeField, {

    /**
     * @private
     * @type CQ.Ext.form.TextField
     */
    hiddenField: null,

    /**
     * @private
     * @type CQ.Ext.form.ComboBox
     */
    allowField: null,

    /**
     * @private
     * @type CQ.Ext.form.TextField
     */
    otherField: null,

    constructor: function(config) {
        config = config || { };
        var defaults = {
            "border": false,
            "layout": "table",
            "columns":2
        };
        config = CQ.Util.applyDefaults(config, defaults);
        Ejst.CustomWidget.superclass.constructor.call(this, config);
    },

    // overriding CQ.Ext.Component#initComponent
    initComponent: function() {
        Ejst.CustomWidget.superclass.initComponent.call(this);

        this.hiddenField = new CQ.Ext.form.Hidden({
            name: this.name
        });
        this.add(this.hiddenField);

        this.allowField = new CQ.form.Selection({
            type:"select",
            cls:"ejst-customwidget-1",
            listeners: {
                selectionchanged: {
                    scope:this,
                    fn: this.updateHidden
                }
            },
            optionsProvider: this.optionsProvider
        });
        this.add(this.allowField);

        this.otherField = new CQ.Ext.form.TextField({
            cls:"ejst-customwidget-2",
            listeners: {
                change: {
                    **scope:this,
                    fn:this.updateHidden**
                }
            }
        });
        this.add(this.otherField);

    },

    // overriding CQ.form.CompositeField#processPath
    processPath: function(path) {
        console.log("CustomWidget#processPath", path);
        this.allowField.processPath(path);
    },

    // overriding CQ.form.CompositeField#processRecord
    processRecord: function(record, path) {
        console.log("CustomWidget#processRecord", path, record);
        this.allowField.processRecord(record, path);
    },

    // overriding CQ.form.CompositeField#setValue
    setValue: function(value) {
        var parts = value.split("/");
        this.allowField.setValue(parts[0]);
        this.otherField.setValue(parts[1]);
        this.hiddenField.setValue(value);
    },

    // overriding CQ.form.CompositeField#getValue
    getValue: function() {
        return this.getRawValue();
    },

    // overriding CQ.form.CompositeField#getRawValue
    getRawValue: function() {
        if (!this.allowField) {
            return null;
        }
        return this.allowField.getValue() + "/" +
               this.otherField.getValue();
    },

    // private
    updateHidden: function() {
        this.hiddenField.setValue(this.getValue());
    }

});

// register xtype
CQ.Ext.reg('ejstcustom', Ejst.CustomWidget);

1 个答案:

答案 0 :(得分:2)

类层次结构,超类构造函数:

您正在调用超类initComponent函数,因为您希望派生类的层次结构的功能可用。

例如,如果你想构建一只大象:

  • 首先设置一些属性,例如“big”,“grey”和“female”。
  • 然后你构建了一种具有这些特性的哺乳动物。
  • 哺乳动物类构造函数本身会设置一些属性,比如“有一个头”,然后调用动物构造函数,所以如果你不用大象叫哺乳动物构造函数,你根本就不会得到一只动物!
  • 动物构造函数将检查属性并创建动物。
  • 然后,哺乳动物类将添加动物类没有覆盖的细节,例如乳房。
  • 哺乳动物构造函数完成后,大象构造函数会添加哺乳类无法覆盖的细节,例如树干。

如果您使用标准的ExtJS语法(不确定CQ是否拥有自己的“标准语法”),大象定义将如下所示:

Ext.define('Elephant',{
    extend:'Mammal',
    initComponent:function() {
        var me = this;
        // set config properties. Two possible calls:
        // "Ext.apply" overwrites config properties already defined by the subclass before constructor has been called
        // "Ext.applyIf" only sets config properties that have NOT been set by the subclass!
        // Since a MiniElephant subclass may want to set size:"small", we use applyIf here.
        Ext.applyIf(me,{ 
            size:'big',
            color:'gray'
        });
        me.callParent(arguments); // <- call constructor of superclass
        me.addTrunk(); // <- postprocessing
    },
    addTrunk:function() {
        var trunk = Ext.create('Trunk',{
            ...
        });
        me.getHead().add(trunk);
        // since addTrunk is called after the mammal constructor has been executed, 
        // the head is already initialized and the getHead function available!
    }
});

Ext.define('Mammal',{
    extend:'Animal',
    initComponent:function() {
        var me = this;
        // Every mammal has a head, so we force the property into here using "apply"!
        Ext.apply({
            hasHead:true,
            ...
        });
        me.callParent(arguments); // <- construct animal
        me.addBreast(); // <- add breast
    },
    getHead:function() {
        return this.headerEl;
    },
    ...
});

监听器范围:

监听器是一个功能。每个函数都有一个所谓的scope,这是从函数内部访问this时将获得的对象。只要您不在函数中使用thisscope对您无关紧要。

默认情况下,在JavaScript中,函数的作用域是函数附加到的对象,所以如果你有一个对象

var listeners = {     更新:function(){         的console.log(本);     } };

如果你这样调用函数:

listeners.update()

它会将侦听器对象记录到控制台;但如果你这样做:

var fn = listeners.update;
fn();

它不会!如果调用函数,则可以设置函数的范围:

listeners.update.call(myScope, firstParameter, secondParameter, ...)

或如果您申请:

listeners.update.apply(myScope, parameterArray)

(要记住: A pply接受 A rray!)

因为,在ExtJS中,侦听器配置由Observable mixin处理,后者将函数放入特制的子对象中,默认范围对ExtJS程序员来说根本没有意义,所以他们已经改变了它。为方便起见,ExtJS添加了一个配置属性,程序员可以使用它来定义函数的预期scope

因此,如果您定义一个面板并在其中添加一个字段:

Ext.apply(me, {
    items:[{
        xtype:'textfield',
        listeners:{
            update:function() {
                console.log(this); // <- returns the panel, because...
            },
            scope:me // <- we are scoping to the panel!
        }
    }
});