How to get access to a window that is loaded into a panel
I'm loading an external script (that creates a new window component) into a 开发者_开发技巧panel, which works fine.
Now, I want to access the created window from a callback function to register a closed
event handler. I've tried the following:
panel.load({
scripts: true,
url: '/createWindow',
callback: function(el, success, response, options) {
panel.findByType("window")[0].on("close", function { alert("Closed"); });
}
});
However, the panel seems to be empty all the time, the findByType
method keeps returning an empty collection. I've tried adding events handlers for events like added
to the panel but none of them got fired.
I don't want to include the handler in the window config because the window is created from several places, all needing a different refresh strategy.
So the question is: how do I access the window in the panel to register my close
event handler on it?
The simplest solution would be to simply include your close handler in the window config that comes back from the server using the listeners
config so that you could avoid having a callback altogether, but I'm assuming there's some reason you can't do that?
It's likely a timing issue between the callback being called (response completed) and the component actually getting created by the ComponentManager. You might have to "wait" for it to be created before you can attach your listener, something like this (totally untested):
panel.load({
scripts: true,
url: '/createWindow',
callback: function(el, success, response, options) {
var attachCloseHandler = function(){
var win = panel.findByType("window")[0];
if(win){
win.on("close", function { alert("Closed"); });
}
else{
// if there's a possibility that the window may not show
// up maybe add a counter var and exit after X tries?
attachCloseHandler.defer(10, this);
}
};
}
});
I got it to work using a different approach. I generate a unique key, register a callback function bound to the generated key. Then I load the window passing the key to it and have the window register itself so that a match can be made between the key and the window object.
This solution takes some plumbing but I think its more elegant and more reliable than relying on timings.
var _windowCloseHandlers = [];
var _windowCounter = 0;
var registerWindow = function(key, window) {
var i;
for (i = 0; i < _windowCounter; i++) {
if (_windowCloseHandlers[i].key == key) {
window.on("close", _windowCloseHandlers[i].closeHandler);
}
}
};
var loadWindow = function(windowPanel, url, params, callback) {
if (params == undefined) {
params = { };
}
windowPanel.removeAll(true);
if (callback != undefined) {
_windowCloseHandlers[_windowCounter] = {
key: _windowCounter,
closeHandler: function() {
callback();
}
};
}
Ext.apply(params, { windowKey: _windowCounter++ });
Ext.apply(params, { containerId: windowPanel.id });
windowPanel.load({
scripts: true,
params: params,
url: url,
callback: function(el, success, response, options) {
#{LoadingWindow}.hide();
}
});
};
Then, in the partial view (note these are Coolite (Ext.Net) controls which generate ExtJs code):
<ext:Window runat="server" ID="DetailsWindow">
<Listeners>
<AfterRender AutoDataBind="true" Handler='<%# "registerWindow(" + Request["WindowKey"] + ", " + Detailswindow.ClientID + ");" %>' />
</Listeners>
</ext:Window>
And finally, the window caller:
loadWindow(#{ModalWindowPanel}, '/Customers/Details', {customerId: id },
function() {
#{MainStore}.reload(); \\ This is the callback function that is called when the window is closed.
});
精彩评论