嗨,我是ExtJs脚本的新手,我试图开发自定义多字段,我能够理解节点创建部分,但在脚本部分,我无法捕获一些东西,如在侦听器中添加范围:this, fn:this。我试着用谷歌搜索答案,但我没有得到任何令人满意的答案。所以谁能给我解释一下范围:这个部分以及为什么我们在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);
类层次结构,超类构造函数:
你正在调用超类initComponent函数,因为你想让派生类的层次结构的功能可用。
例如,如果你想构造一个大象:
- 首先,你设置一些属性,如"大"one_answers"灰色"one_answers"女性"。
- 然后你构建一个哺乳动物与这些属性。 哺乳动物类的构造函数会自己设置一些属性,比如"has a head",然后调用动物的构造函数,所以如果你不从elephant调用哺乳动物的构造函数,你根本就没有得到一个动物!
- 动物构造器将检查属性并创建一个动物。
- 然后,哺乳动物类将添加动物类没有涵盖的细节,例如乳房。
- 哺乳动物构造函数完成后,大象构造函数添加哺乳动物类没有涉及的细节,例如躯干。
如果你要使用标准的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
时得到的对象。只要你在函数中不使用this
, scope
对你来说是无关紧要的。
默认情况下,在JavaScript中,函数的作用域是该函数所附加的对象,所以如果你有一个对象
var listener = {更新:函数(){console.log(这个);}
};如果你像这样调用函数:
listeners.update()
它将把监听对象记录到控制台;但是如果你这样做:
var fn = listeners.update;
fn();
它不会!可以通过调用以下函数来设置函数的作用域:
listeners.update.call(myScope, firstParameter, secondParameter, ...)
或者
listeners.update.apply(myScope, parameterArray)
(好记住:的页的的 rray !)
因为,在ExtJS中,监听器的配置是由一个Observable mixin处理的,它把函数放入了特别制作的子对象中,默认的作用域对ExtJS程序员来说根本没有意义,所以他们改变了它。为了方便,ExtJS添加了一个config属性,程序员可以使用它来定义他想要的函数的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!
}
}
});
标题>