tags:

views:

186

answers:

2

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?

A: 

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);
            }
        };
    }
});
bmoeskau
Thanks. I've updated the question to explain why I don't want to include the close handler in the window config. I can't test your solution right now but I will as soon as I can. I don't like fixing timing issues with timers though (I think it isn't preferable practice) and I'm still wondering if there's a way to catch an event that is (should be?) raised when the rendering finishes.
Sandor Drieënhuizen
A: 

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.
    });
Sandor Drieënhuizen