PDA

View Full Version : Closing and recreating portlets (using portal example)...



RodS1967
8 Feb 2012, 10:06 AM
Using the portal example from the examples library, I was trying to create and close and then recreate portlets dynamically. I don't have a problem creating them, and I can create several without issue. Once I close one, I can't create them any more though.I've tried adding a call to portlet.doClose to the onPortletClose method, I've tried removing the overridden method of the same name on the portlet class; nothing seems to be helping. I'm new to ExtJS and I'm thinking it may have something to do with the cleanup process and I'm just not doing something right. Does anyone have any ideas on this? My modified source code is below.



/**
* @class Ext.app.Portal
* @extends Object
* This is from the portal layouts example in ExtJS documentation.
*/
Ext.Loader.setPath('Ext.app', '/app/classes');

Ext.require([

'Ext.layout.container.*',
'Ext.resizer.Splitter',
'Ext.fx.target.Element',
'Ext.fx.target.Component',
'Ext.window.Window',
'Ext.app.Portlet',
'Ext.app.PortalColumn',
'Ext.app.PortalPanel',
'Ext.app.Portlet',
'Ext.app.PortalDropZone'
]);

Ext.define('Ext.app.Portal', {

extend: 'Ext.container.Viewport',
uses: [
'Ext.app.PortalPanel',
'Ext.app.PortalColumn'
],

getTools: function(){
return [{
xtype: 'tool',
type: 'gear',
handler: function(e, target, panelHeader, tool){
var portlet = panelHeader.ownerCt;
portlet.setLoading('Loading...');
Ext.defer(function() {
portlet.setLoading(false);
}, 2000);
}
}];
},

initComponent: function(){
var content = '<div class="portlet-content">Testing material content for a portlet</div>';

Ext.apply(this, {
id: 'app-viewport',
layout: {
type: 'border',
padding: '0 5 5 5' // pad the layout from the window edges
},
items: [{
id: 'app-header',
xtype: 'box',
region: 'north',
height: 40,
html: 'Portal'
},{
xtype: 'container',
region: 'center',
layout: 'border',
items: [{
id: 'app-options',
title: 'Options',
region: 'west',
animCollapse: true,
width: 200,
minWidth: 150,
maxWidth: 400,
split: true,
collapsible: true,
layout:{
type: 'accordion',
animate: true
},
items: [{
title:'Browse',
autoScroll: true,
border: false,
iconCls: 'record-find',
flex: 1,
layout: 'vbox',
items: [
{
xtype: 'button',
text: 'Test',
iconAlign: 'left',
listeners: {
'click': Ext.bind(this.onPortletOpen, this)
}
}
]
}]
},{
id: 'app-portal',
xtype: 'portalpanel',
region: 'center',
items: [
{
items: [
]
},
{
items: [
]
},
{
items: [
]
}
]
}]
}]
});

this.clearMsg(this.msgId);
this.callParent(arguments);
},

onPortletOpen: function (button) {
//window.location="/planning/product";

// check if this portlet is already there, if not, add it
// if so, focus the one that is found, and bring to forefront (and perhaps unmimimize it)

this.showMsg('Clicked portlet open. Button = ' + button.text);
// cheesy, but works for now
var portal = Ext.getCmp('app-portal');
portal.items.items[0].items.add(Ext.widget('portlet', {
title: button.text,
height: 300,
listeners: {
'close': Ext.bind(this.onPortletClose, this)
}
}));
portal.items.items[0].doComponentLayout();
},

onPortletClose: function(portlet) {
this.showMsg('"' + portlet.title + '" was removed');
portlet.doClose;
},

showMsg: function(msg) {
var el = Ext.get('app-msg'),
msgId = Ext.id();

this.msgId = msgId;
el.update(msg).show();

Ext.defer(this.clearMsg, 3000, this, [msgId]);
},

clearMsg: function(msgId) {
if (msgId === this.msgId) {
Ext.get('app-msg').hide();
}
}
});

mitchellsimoens
8 Feb 2012, 12:33 PM
Why can't you recreate one? Are you using Ext.create or new to create it or trying to recreate one that you removed?

RodS1967
8 Feb 2012, 1:03 PM
I am adding the portlet via a call to onPortletOpen, the meat of which is...




var portal = Ext.getCmp('app-portal'); portal.items.items[0].items.add(Ext.widget('portlet', { title: button.text, height: 300, listeners: { 'close': Ext.bind(this.onPortletClose, this) } })); portal.items.items[0].doComponentLayout();


Like I said, I can create multiple portlets without issue... until I close one. Then it all falls apart. If you take my code and just overwrite the original portal.js with it, you can easily see what I mean.

sskow200
8 Feb 2012, 2:24 PM
var portal = Ext.get('app-portal'),
firstColumn = portal.down('portalcolumn');

firstColumn.add(Ext.create('Ext.app.Portlet', {
title: 'New Portlet',
html: 'this is a new portlet'
});


Am I just not understanding the issue?

RodS1967
9 Feb 2012, 8:19 AM
Creating them initially is not the issue. It only becomes a problem after I delete one or more of the portlets I created dynamically. After that I get wierd null value errors and new portlets cannot be created

sskow200
9 Feb 2012, 8:47 AM
You shouldn't have to call doComponentLayout() when adding them from the container. Why have you added this on the 'add' event?

sskow200
9 Feb 2012, 8:50 AM
As far as I can tell

portlet.doClose;

does nothing for you. You meant

portlet.doClose(); ??

In which case, you need to make sure you destroy the components after removing them.

closeAction: 'destroy'

RodS1967
9 Feb 2012, 9:06 AM
The closeAction assignment may be what I need. Thanks. I'll try that out.

sskow200
9 Feb 2012, 9:15 AM
It also may be easier for you to extend the portlet class and add the close functionality that you're looking for it to it. This encapsulates the action within the portlet itself. For example:



Ext.define('MyPortlet', {
extend: 'Ext.app.Portlet',
alias: 'widget.myportlet',

doClose: function() {
this.callParent(arguments);
console.log(this.title + ' portlet was removed');
}
}):


This allows you to maintain the scope w/out binding a new outside function to each portlet you create.

RodS1967
9 Feb 2012, 9:24 AM
This was actually part of a bigger picture but I slimmed it way down to the very basics where I could replicate the issue. In the bigger picture, we are extending classes as well as encapsulating new ones within the portlets we create. We originally thought our classes were the problem, but then realized that removing them didn't solve the problem. I expect that we may find the same issue with them once we fix the portlets.

sskow200
9 Feb 2012, 9:33 AM
Understood. You may also want to try not referring directly to the items object to add your components. This will remove the need to perform doComponentLayout(); every time you add one. Simply grab the instance of your column and call that 'add' operation on the component itself. The layout engine will automatically take care of the rest for you.

RodS1967
9 Feb 2012, 10:28 AM
Actually, your last suggestion is what wound up solving the issue. It must have had something to do with the way I was adding the portlet to the column. I changed the line "portal.items.items[0].items.add(Ext.widget(..." to "portal.items.items[0].add(Ext.widget(..." and I no longer have the issue after I close portlets. I also no longer need to call doComponentLayout like you suggested.

Thanks much!

~Rod

sskow200
9 Feb 2012, 10:57 AM
Glad this was resolved for you.