在 Sencha 应用程序中重用相同组件时出现重复引用
Duplicate references when reusing the same component in Sencha app
假设我们已经定义了一个组件(例如 FieldSet),我们希望在单个应用程序中重用它(例如 display/use 它在 2 种不同的模式 windows 中)。这个 FieldSet 有一个参考,我们用它来访问它。目标是让这 2 windows 包含 独立 字段集,这样我们就可以分别控制和收集每个字段的输入。
这是演示问题的示例 fiddle。只要任何函数触发任何 lookupReference(...)
调用,Sencha 就会发出字段集“重复引用”的警告。它在每个 window 上正确地创建了两个不同的字段集组件(通过分配不同的 ID),但未能正确地 assign/locate 引用。因此,对这些 windows' 字段集之一的任何操作都将在“未知”字段上执行(可能是在第一个创建的字段上),从而扰乱 UI 行为。
我知道 Sencha 在对引用进行操作时理解使用哪个组件是个问题,但应该有一种方法可以多次重用同一组件而不会混淆实例。非常感谢任何帮助。
根据 ViewController 上的文档:
A view controller is a controller that can be attached to a specific view instance so it can manage the view and its child components. Each instance of the view will have a new view controller, so the instances are isolated.
这意味着您在 ViewController 上使用 singleton
是不正确的,因为它必须绑定到单个视图实例。
要解决此问题,我建议对您的 Fiddle 进行一些修改,主要是从 VC class 中删除 singleton: true
,通过 lookup
,并通过 getController
获取他们的 VC 以访问您的 func
方法。
Ext.application({
name: 'Fiddle',
launch: function () {
/**
* @thread
*/
Ext.define('fsContainerHandler', {
extend: 'Ext.app.ViewController',
alias: 'controller.fsContainerHandler',
// TOOK OUT singleton: true
func: function () {
var x = this.lookupReference('fsRef');
alert(x);
}
});
Ext.define('fsContainer', {
extend: 'Ext.container.Container',
xtype: 'xFSContainer',
controller: 'fsContainerHandler',
items: [{
xtype: 'fieldset',
title: 'myFieldset',
reference: 'fsRef'
}]
});
Ext.define('mainContainerHandler', {
extend: 'Ext.app.ViewController',
alias: 'controller.mainContainerHandler',
singleton: true,
onButton1Click: function () {
var win = this.getView().window1;
win.show();
// CHANGED LOGIC
win.lookup('theContainer').getController().func();
},
onButton2Click: function () {
var win = this.getView().window2;
win.show();
// CHANGED LOGIC
win.lookup('theContainer').getController().func();
}
});
Ext.define('mainContainer', {
extend: 'Ext.container.Container',
width: 400,
controller: 'mainContainerHandler',
window1: null,
window2: null,
initComponent: function () {
this.window1 = Ext.create('window1');
this.window2 = Ext.create('window2');
this.callParent(arguments);
},
items: [{
xtype: 'button',
text: 'Window 1',
reference: 'btn1',
handler: mainContainerHandler.onButton1Click,
scope: mainContainerHandler
}, {
xtype: 'button',
text: 'Window 2',
reference: 'btn2',
handler: mainContainerHandler.onButton2Click,
scope: mainContainerHandler
}]
});
Ext.define('window1', {
extend: 'Ext.window.Window',
title: 'Window1',
modal: true,
width: 100,
height: 100,
closeAction: 'hide',
// ADDED referenceHolder
referenceHolder: true,
items: [{
xtype: 'xFSContainer',
// ADDED reference
reference: 'theContainer'
}]
});
Ext.define('window2', {
extend: 'Ext.window.Window',
title: 'Window2',
modal: true,
width: 100,
height: 100,
closeAction: 'hide',
// ADDED referenceHolder
referenceHolder: true,
items: [{
xtype: 'xFSContainer',
// ADDED reference
reference: 'theContainer'
}]
});
Ext.create('mainContainer', {
renderTo: document.body
});
}
});
假设我们已经定义了一个组件(例如 FieldSet),我们希望在单个应用程序中重用它(例如 display/use 它在 2 种不同的模式 windows 中)。这个 FieldSet 有一个参考,我们用它来访问它。目标是让这 2 windows 包含 独立 字段集,这样我们就可以分别控制和收集每个字段的输入。
这是演示问题的示例 fiddle。只要任何函数触发任何 lookupReference(...)
调用,Sencha 就会发出字段集“重复引用”的警告。它在每个 window 上正确地创建了两个不同的字段集组件(通过分配不同的 ID),但未能正确地 assign/locate 引用。因此,对这些 windows' 字段集之一的任何操作都将在“未知”字段上执行(可能是在第一个创建的字段上),从而扰乱 UI 行为。
我知道 Sencha 在对引用进行操作时理解使用哪个组件是个问题,但应该有一种方法可以多次重用同一组件而不会混淆实例。非常感谢任何帮助。
根据 ViewController 上的文档:
A view controller is a controller that can be attached to a specific view instance so it can manage the view and its child components. Each instance of the view will have a new view controller, so the instances are isolated.
这意味着您在 ViewController 上使用 singleton
是不正确的,因为它必须绑定到单个视图实例。
要解决此问题,我建议对您的 Fiddle 进行一些修改,主要是从 VC class 中删除 singleton: true
,通过 lookup
,并通过 getController
获取他们的 VC 以访问您的 func
方法。
Ext.application({
name: 'Fiddle',
launch: function () {
/**
* @thread
*/
Ext.define('fsContainerHandler', {
extend: 'Ext.app.ViewController',
alias: 'controller.fsContainerHandler',
// TOOK OUT singleton: true
func: function () {
var x = this.lookupReference('fsRef');
alert(x);
}
});
Ext.define('fsContainer', {
extend: 'Ext.container.Container',
xtype: 'xFSContainer',
controller: 'fsContainerHandler',
items: [{
xtype: 'fieldset',
title: 'myFieldset',
reference: 'fsRef'
}]
});
Ext.define('mainContainerHandler', {
extend: 'Ext.app.ViewController',
alias: 'controller.mainContainerHandler',
singleton: true,
onButton1Click: function () {
var win = this.getView().window1;
win.show();
// CHANGED LOGIC
win.lookup('theContainer').getController().func();
},
onButton2Click: function () {
var win = this.getView().window2;
win.show();
// CHANGED LOGIC
win.lookup('theContainer').getController().func();
}
});
Ext.define('mainContainer', {
extend: 'Ext.container.Container',
width: 400,
controller: 'mainContainerHandler',
window1: null,
window2: null,
initComponent: function () {
this.window1 = Ext.create('window1');
this.window2 = Ext.create('window2');
this.callParent(arguments);
},
items: [{
xtype: 'button',
text: 'Window 1',
reference: 'btn1',
handler: mainContainerHandler.onButton1Click,
scope: mainContainerHandler
}, {
xtype: 'button',
text: 'Window 2',
reference: 'btn2',
handler: mainContainerHandler.onButton2Click,
scope: mainContainerHandler
}]
});
Ext.define('window1', {
extend: 'Ext.window.Window',
title: 'Window1',
modal: true,
width: 100,
height: 100,
closeAction: 'hide',
// ADDED referenceHolder
referenceHolder: true,
items: [{
xtype: 'xFSContainer',
// ADDED reference
reference: 'theContainer'
}]
});
Ext.define('window2', {
extend: 'Ext.window.Window',
title: 'Window2',
modal: true,
width: 100,
height: 100,
closeAction: 'hide',
// ADDED referenceHolder
referenceHolder: true,
items: [{
xtype: 'xFSContainer',
// ADDED reference
reference: 'theContainer'
}]
});
Ext.create('mainContainer', {
renderTo: document.body
});
}
});