Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Over 10 years of community discussion and knowledge are maintained here as a read-only archive.

New discussions should be taken up in issues on the appropriate projects at https://github.com/PureMVC

Pages: [1]
Print
Author Topic: Using JS-Signals with View Components  (Read 10226 times)
mikebritton
Full Member
***
Posts: 42


View Profile Email
« on: September 21, 2012, 11:03:54 »

I wanted to post this because I'm having a lot of luck with JS-Signals http://millermedeiros.github.com/js-signals/ in the Views and Mediators of a jQuery-based application, specifically around the area of handling user interaction from viewComponent.  Obviously there are alternatives, but this one is turning out to be fairly clean and straightforward.

I'm using:

I'm instantiating a new view component on the Mediator's on Register, and calling setViewComponent(). 

:
/**
 * @author Mike Britton
 *
 * @class ScrollerMediator
 *
 *
 *
 */

puremvc.define({
    name : 'rps.view.mediator.ScrollerMediator',
    parent : puremvc.Mediator
},
// INSTANCE MEMBERS
{
    /** @override */
    listNotificationInterests : function() {
        return [rps.AppConstants.NOTE_PAGES_RETRIEVED,rps.AppConstants.NOTE_APP_RESIZE];
    },
    /** @override */
    onRegister : function() {
       
        // Create the viewComponent
        this.setViewComponent(new rps.view.component.ScrollerComponent);
       
        // Establish signal listeners
        this.doSignals();
       
    },
    /** @override */
    handleNotification : function(note) {
        //console.log('ScrollerMediator::handleNotification - ' + note.getName());

        switch (note.getName()) {
            case rps.AppConstants.NOTE_APP_RESIZE:
                this.getViewComponent().updateUI(note.getBody());
                this.doSignals();
                break;
            case rps.AppConstants.NOTE_PAGES_RETRIEVED:
                this.getViewComponent().build(note.getBody());
                break;
        }
    },
    doSignals:function(){
        var target = this;
        $.each(this.getViewComponent().signals, function(index, item) {
           if (!item.has(target.handleEvent)) {
               // Second arg is scope
               item.add(target.handleEvent, target);
           }
        });     
    },
    handleEvent : function(signal) {
       switch(signal){
           case rps.view.component.ScrollerComponent.SIGNAL_READY:
              //console.log('ScrollerMediator::Signal '+signal+' received');
           break;
       };

    }
},
// STATIC MEMBERS
{
    /**
     * @static
     * @type {string}
     */
    NAME : 'ScrollerMediator'
});

Inside the view component, I call build() and use underscore.js to retrieve templates:

:
var comp = _.template($('#stripsTmpl').html());

An underscore template looks like this in HTML:

:
<script type="text/template" id="stripsTmpl">
    <div id="pagesX" class="pagesX" style="width:<%- pagesXWidth %>px;height:<%- pagesXHeight %>px;"></div>
    <div id="pagesY" style="position:absolute;width:<%- pagesYWidth %>px;height:<%- pagesYHeight %>px;"></div>
</script>

Back in my component class, I have public signals[], each key being a new signals.Signal(). In my Mediator, I call doSignals() once the viewComponent has been created, and set a single handler (see above) for all signals.  All user interactions in the viewComponent dispatch Signals back to the Mediator's handleEvent().

Scope issues between viewComponent and Mediator are handled with a Signals context argument:

:
doSignals:function(){
    var target = this;
    $.each(this.getViewComponent().signals, function(index, item) {
       if (!item.has(target.handleEvent)) {
           // Second arg is scope
           item.add(target.handleEvent, target);
       }
    });     
},

Why use Signals?  I don't want to troubleshoot native events until their implementation stabilizes across browsers and platforms.  (At least not for client projects.)  I want to abstract them, to keep my architecture safe from contamination by proprietary hocus-pocus with respect to event programming.  Not sure if this is the right approach, but it feels right.

Hope this proves useful, either directly or as an example of how not to do it!   ;D


Mike
Logged
Pages: [1]
Print