Direct interaction between different modules without page reload

LabKey Support Forum (Inactive)
Direct interaction between different modules without page reload Leo Dashevskiy  2013-02-15 09:08
Status: Closed
 
Is there any mechanism to let one module know that something happened in another module (data loaded into db by the latter, so that the former can reload its data sources)? (Right now I have to reload the page for the former to refresh its sources, which is not convenient...)

where my modules each are of this form:

<script type='text/javascript'>

    var initOpenCyto<moduleName> = function(){
        var webPartDiv = <%=webpartContext%>.wrapperDivId;

        var OpenCyto<moduleName> = new LABKEY.ext.OpenCyto<moduleName>({
            webPartDivId: webPartDiv
        });
    }

    Ext.onReady( initOpenCyto<moduleName> );

</script>
 
 
Anthony Corbett responded:  2013-02-15 12:58

I've thought about this same use case. Not sure how helpful my thoughts will be, but here they are:

First, you don't want direct interaction between modules. To decouple the modules, each should implement/mixin Ext.util.Observable (http://docs.sencha.com/ext-js/4-1/#!/api/Ext.util.Observable) so it can fire events and other modules/components can listen. The Observable API also allows you to define listeners in the config. Using listeners allows you to invoke a method on another module in a listener callback function.

There are draw back to defining listener callbacks that directly invoke another module's method, namely that an instance of the dependent module must be in scope and thus there is a runtime load and initialization dependencies between the two.


Ideally, you need a middle man [object] that can handle 'wiring' together different modules, this is called a mediator and would be the only dependency for each module. The mediator could implement a publish subscribe event system. Modules subscribe to certain events (also called topics) and any module can publish an event (topic)

Here is an example of an Ext plugin called MsgBus which uses events to communicate between components: http://examples.extjs.eu/?ex=msgbus


Would be nice for something in the LABKEY namespace to provide a global singleton mediator for exactly this use case (pub/sub).


Also you don't need to use any variable declaration to create your module instance:


<script type='text/javascript'>

    Ext.onReady( function(){
        new LABKEY.ext.OpenCyto<moduleName>({
            webPartDivId: <%=webpartContext%>.wrapperDivId
        });
    });

</script>



-
Anthony
 
Leo Dashevskiy responded:  2013-02-15 15:41
Thanks, Anthony!

It is nice to hear that someone else has thought about the same issue and in fact has come to the same conclusion.

I already realized the weakness of the Observable that the 2 communicating modules must be in the same scope, which is at time troublesome and have also read up on the MsgBus and Mediator (pub/sub) ideas.

I think, I will give those last ones a stab.


And as far as the module instance goes, I do have more going on than the trimmed version above, namely:

<script type='text/javascript'>

    var initOpenCytoPreprocessing = function(){
        var webPartDiv = <%=webpartContext%>.wrapperDivId;

        var resizeModule;
        var OpenCytoPreprocessing = new LABKEY.ext.OpenCytoPreprocessing({
            webPartDivId: webPartDiv
        });

            captureEvents( OpenCytoPreprocessing );

        resizeModule = function(w, h){

            LABKEY.Utils.resizeToViewport( OpenCytoPreprocessing, w, -1, null, null, -5 );

            OpenCytoPreprocessing.resize();
        };

        Ext.EventManager.onWindowResize( resizeModule );
        Ext.EventManager.fireWindowResize();

    }

    Ext.onReady( initOpenCytoPreprocessing );

</script>
 
Leo Dashevskiy responded:  2013-07-01 11:56
Works with saki's MsgBus.js approach