Extjs: How to approach the concept: Add, remove, add instance
Concept:
Consider having two panels A
and B
, and a window C
开发者_开发技巧 like in the following example. The buttons on the window switches between the two panels.
var A = new Ext.Panel({
title: 'A'
});
var B = new Ext.Panel({
title: 'B'
});
var C = new Ext.Window({
layout: 'fit',
width: 300,
height: 300,
items: A,
buttons: [
{
text: 'Switch to A',
handler: function() {
C.removeAll(false);
C.add(A);
C.doLayout();
}
}, {
text: 'Switch to B',
handler: function() {
C.removeAll(false);
C.add(B);
C.doLayout();
}
}]
});
C.show();
The concept is very simple: Add a component, remove it and add the same instance again.
Problem: The switch from A to B works, but going back to A doesn't (B stays and A is not shown again).
Question: Thinking OOP, I would expect the above concept to work. Since this is not the case and its a very basic manouvre, how should I think / contemplate / design when I'm trying to do this?
I understand that there might be varying cases when considering a FormPanel vs. other layouts/components - but there must be a general and correct way to do this :)
Perhaps a card
layout is exactly what you need:
var C = new Ext.Window({
layout: 'card',
width: 300,
height: 300,
activeItem: 0,
items: [A, B],
buttons: [{
text: 'Switch to A',
handler: function() {
C.getLayout().setActiveItem(0);
}
}, {
text: 'Switch to B',
handler: function() {
C.getLayout().setActiveItem(1);
}
}]
});
C.show();
I assume the problem with your code is that you're reusing the same instance again. Ext internally sets a rendered
-flag on a component once it has been written to the DOM tree. As the rendered
flag is still true after you removed the component from C
it won't be redrawn when you add the component again.
A simple modification will make your code work: add A.rendered = false;
and B.rendered = false
respectively before you call C.doLayout()
in your button handlers.
But still the card-layout approach would be best-practice.
I've found a simple solution, but it's more of a hack. After removing the component (your A or B panel), you have to add it to another container which must to be rendered. Here is an example in which the panels get moved to a hidden container:
var A = new Ext.Panel({
title: 'A'
});
var B = new Ext.Panel({
title: 'B'
});
var C = new Ext.Window({
layout: 'fit',
width: 300,
height: 300,
items: A,
buttons: [
{
text: 'Switch to A',
handler: function() {
C.remove(B, false);
T.add(B);
C.add(A);
C.doLayout();
}
}, {
text: 'Switch to B',
handler: function() {
C.remove(A, false);
T.add(A);
C.add(B);
C.doLayout();
}
}]
});
var T = new Ext.Container({
renderTo: "temporaryContainer",
renderHidden: true
});
C.show();
And somewhere in the page's body you need to have this:
<div id="temporaryContainer" class="x-hidden"></div>
Tested with ExtJs 4.0.2a.
精彩评论