为什么 ExtJS 'items' 属性 表现得像静态的?
Why ExtJS 'items' property behaves like static?
每次调用 Ext.create()
时,新按钮都会推送到表单。但是counter
还是离开了== 1
如果我删除 items: []
并取消注释 Ext.apply(/*...*/)
一切正常。
为什么 items
属性 表现得像静态的?
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.define('TestForm', {
extend: 'Ext.form.Panel',
title: 'TestForm',
margin: 40,
items: [], // remove it
counter: 100,
initComponent: function() {
this.counter++;
/*Ext.applyIf(this, {
items: []
});*/
this.items.push({ xtype: 'button', text: 'test'+this.counter})
this.callParent(arguments);
},
renderTo: Ext.getBody()
})
Ext.create('TestForm');
Ext.create('TestForm');
Ext.create('TestForm');
}
});
当组件派生自原型时,所有成员都会被传递 - 一些通过引用,一些通过值,具体取决于类型。
- 计数器是一个int,按值传递。
- Items 是一个数组,通过引用传递。
因此,如果您在原型上定义 items
数组,所有实例都指向同一个 items
数组。
由于您将按钮配置添加到该数组(其中有两个引用,一个来自原型,一个来自实例),每次您创建一个新实例时,都会向该数组添加一个新按钮,保留旧的。
之后,在 callParent
中,ExtJS 迭代项目 属性(然后是一个数组)并从数组内容创建一个组件的 MixedCollection。然后将 mixedCollection 存储在项目 属性 中。在此期间,引用中断 - 这就是为什么第一个实例没有将第二个按钮放入其项目中的原因。
为确保您不会 运行 陷入这些问题,有一种可能:
永远不要将引用传递类型定义为原型的成员。
我会做什么:
Ext.define('TestForm', {
extend: 'Ext.form.Panel',
title: 'TestForm',
margin: 40,
counter: 100,
initComponent: function() {
this.counter++;
Ext.apply(this, {
items: [{ xtype: 'button', text: 'test'+this.counter}]
});
this.callParent(arguments);
},
renderTo: Ext.getBody()
})
或
Ext.define('TestForm', {
extend: 'Ext.form.Panel',
title: 'TestForm',
margin: 40,
counter: 100,
initComponent: function() {
this.counter++;
this.callParent(arguments);
this.add({xtype: 'button', text: 'test'+this.counter});
},
renderTo: Ext.getBody()
})
第一个在实例化组件之前将项目定义添加到每个实例,另一个在组件实例化之后将按钮添加到布局。
每次调用 Ext.create()
时,新按钮都会推送到表单。但是counter
还是离开了== 1
如果我删除 items: []
并取消注释 Ext.apply(/*...*/)
一切正常。
为什么 items
属性 表现得像静态的?
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.define('TestForm', {
extend: 'Ext.form.Panel',
title: 'TestForm',
margin: 40,
items: [], // remove it
counter: 100,
initComponent: function() {
this.counter++;
/*Ext.applyIf(this, {
items: []
});*/
this.items.push({ xtype: 'button', text: 'test'+this.counter})
this.callParent(arguments);
},
renderTo: Ext.getBody()
})
Ext.create('TestForm');
Ext.create('TestForm');
Ext.create('TestForm');
}
});
当组件派生自原型时,所有成员都会被传递 - 一些通过引用,一些通过值,具体取决于类型。
- 计数器是一个int,按值传递。
- Items 是一个数组,通过引用传递。
因此,如果您在原型上定义 items
数组,所有实例都指向同一个 items
数组。
由于您将按钮配置添加到该数组(其中有两个引用,一个来自原型,一个来自实例),每次您创建一个新实例时,都会向该数组添加一个新按钮,保留旧的。
之后,在 callParent
中,ExtJS 迭代项目 属性(然后是一个数组)并从数组内容创建一个组件的 MixedCollection。然后将 mixedCollection 存储在项目 属性 中。在此期间,引用中断 - 这就是为什么第一个实例没有将第二个按钮放入其项目中的原因。
为确保您不会 运行 陷入这些问题,有一种可能: 永远不要将引用传递类型定义为原型的成员。
我会做什么:
Ext.define('TestForm', {
extend: 'Ext.form.Panel',
title: 'TestForm',
margin: 40,
counter: 100,
initComponent: function() {
this.counter++;
Ext.apply(this, {
items: [{ xtype: 'button', text: 'test'+this.counter}]
});
this.callParent(arguments);
},
renderTo: Ext.getBody()
})
或
Ext.define('TestForm', {
extend: 'Ext.form.Panel',
title: 'TestForm',
margin: 40,
counter: 100,
initComponent: function() {
this.counter++;
this.callParent(arguments);
this.add({xtype: 'button', text: 'test'+this.counter});
},
renderTo: Ext.getBody()
})
第一个在实例化组件之前将项目定义添加到每个实例,另一个在组件实例化之后将按钮添加到布局。