Geoff,

After some testing I can really see the benefits in how you achieve this... One of my main prior misunderstanding was that the 'define' is only run once (I thought it would be re-run each 'require'), making similar to a 'static' object in some ways, in that the state is then shared by all subsequent 'require' calls... so you are effectively creating a hash of stateful objects within the context of that 'define'.

thank you for helping me understand this, I feel I have graduated re this concept and can now get some code written.

would love to see this in action in jumpstart7. as far as i'm concerned jumpstart is the definitive tapestry documentation, or at least on par with the official.

howard, thiago etc, maybe putting a few more complex examples in the 'javascript-modules' documentation would be helpful? if you haven't used requirejs before this concept is hard to grasp at first.

p.

On 14/11/2014 3:06 PM, Geoff Callender wrote:
I accidentally left out the object's state vars. Added below.

On 14 Nov 2014, at 10:00 am, Geoff Callender 
<geoff.callender.jumpst...@gmail.com> wrote:

Yep, that's a valid case, and it's one I have to put into JumpStart.

Here's the way I handle it. I'd like to see what others do.

Have the module keep an array of objects, identified by a key. The server-side 
can provide the key when initialising and later whenever invoking a function. 
The component can use any value for the key as long as it is unique on the page 
and as long as it is repeatable (eg. the component might need to derive the key 
from its container or context).

Here's an example snippet from a module I called "activate-selectables". More 
than one component on my page uses this module. A typical case is when I have a list of 
items on the page, and a button that pops up a modal with another list of items. When an 
item is selected, the server-side has to set the currentElement on the correct list.

define([ "jquery", "t5/core/console" ], function($, console) {

        var selectablesContainers = [];

        SelectablesContainer = function() {
                var containerId = "", selectableClass = "", selectedClass = "", 
currentClass = "";

                init = function(params) {
                        containerId = params.containerId;
                        selectableClass = params.selectableCssClass;
                        selectedClass = params.selectedCssClass;
                        // etc
                        var $container = $('#' + containerId);
                        $container.on('click', '.' + selectableClass, 
doSelected);
                };

                doSelected = function() {
                        var $clicked = $(this);
                        $clicked.addClass(selectedClass);
                        $clicked.trigger('selected');
                };

                setCurrentElement = function(selectableName) {
                        // etc.
                };

                return {
                        init : init,
                        setCurrentElement : setCurrentElement
                };
        };

        init = function(key, params) {
                var selectablesContainer = new SelectablesContainer();
                selectablesContainer.init(params);
                selectablesContainers[key] = selectablesContainer;
        };

        setCurrentElement = function(key, currentElementName) {
                var selectablesContainer = selectablesContainers[key];
                selectablesContainer.setCurrentElement(currentElementName);
        };

        return {
                init : init,
                setCurrentElement : setCurrentElement
        };

});

And some corresponding java:

        void afterRender() {
                JSONObject params = new JSONObject();
                params.put("containerId", thingsDiv.getClientId());
                //etc
                
javaScriptSupport.require("activate-selectables").invoke("init").with(SELECTABLES_KEY,
 params);
        }

        Object onThingSelected(Integer thingId) {
                this.thingId = thingId;
                // etc
                
ajaxResponseRenderer.addCallback(makeScriptToSetCurrentElement(selectableName));
                // etc
        }

        private JavaScriptCallback makeScriptToSetCurrentElement(final String 
selectableName) {

                return new JavaScriptCallback() {

                        public void run(JavaScriptSupport javaScriptSupport) {
                                
javaScriptSupport.require("activate-selectables").invoke("setCurrentElement")
                                                .with(SELECTABLES_KEY, 
selectableName);
                        }

                };

        }

In this case I get away with SELECTABLES_KEY being a constant but, as I said 
above, sometimes you have to derive its value from its container or event 
context.

Geoff

On 14 Nov 2014, at 9:18 am, Paul Stanton <pa...@mapshed.com.au> wrote:

Oh,

so calling
require("modal").invoke("activate")

and then later
require("modal").invoke("deactivate")

.. both re-construct a seperate "modal" js object and then call one of the two 
published functions...

what if you have two different modals? what if they are init-ed differently:

java:afterRender() {
    require("modal").invoke("init").with("message 1");
    require("modal").invoke("init").with("message 2");
}

and then later
java:onSomeEvent() {
    require("modal").invoke("activate");
}

this flow would essentially construct the modal module instance 3 times, and the "activate" 
wouldn't know about "message 1" or "message 2".

Therefore, how would I re-aquire a handle to a specific module instance later 
on? for eg:

java:onSomeEvent(){
    // activate modal with "message 1"
    require("modal").invoke("activate");
}

I know this example doesn't make much practical sense, but the concept of 
communicating with something stateful is pretty key!

p.

On 13/11/2014 4:34 PM, Geoff Callender wrote:
Have you had a look at these two:

        
http://jumpstart.doublenegative.com.au/jumpstart7/examples/javascript/modal/1
        
http://jumpstart.doublenegative.com.au/jumpstart7/examples/javascript/reusablemodal/1

Do they fit your scenario?

On 13 Nov 2014, at 3:40 pm, Paul Stanton <pa...@mapshed.com.au> wrote:

Hi Geoff,

I have found your examples invaluable in learning some of the basics of this 
(and other) concepts. I can't thank you enough

.. the only thing I can see is missing currently is the example I asked about 
in the previous mail:

Basically, how do I interact with a js module instance after it is created?

pretend some server-side state changes between afterRender and onSomeEvent, and 
the client needs to react accordingly.

jss.addScript is deprecated, so I "shouldn't" be telling the client to execute 
script apparently...

cheers, p.

On 13/11/2014 2:36 PM, Geoff Callender wrote:
do these examples cover the situations you are describing?
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org

Reply via email to