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

Show Posts

* | |

  Show Posts
Pages: [1]
1  PureMVC Manifold / Multicore Version / Pipes Utility for PureMVC - Javascript Native Port on: October 18, 2012, 08:36:03
I created a native Javascript port of the PureMVC Pipes Utility.  I also have a Dojo version contained inside my Dojo-PureMVC implementation, but since the PureMVC Native JS port is the defacto standard, I created a matching Pipes version.  Although it probably needs some refinement in places, it appears to work fine for me.

You can get it here and read about it here

There is also a src directory with an implementation created with the puremvc.define utility which I like much better.  It makes the OO structure easy to see and understand.  However, since the main PureMVC JS distribution is written with prototypes, the primary src directory follow suit. I've also posted demos showing it in action with the source included on GitHub.  (They are based on Tekool's excellent actionscript Pipes demo)

If anyone wants to add it to the official PureMVC distribution site, I'm fine with that too.    :)
2  PureMVC Manifold / Demos and Utils / Re: Dojo AMD Implementation of PureMVC and Pipes on: October 17, 2012, 11:57:22
I've created a couple of demos on using the Native PureMVC-JS implementation with the Dojo Toolkit based on Cliff's suggestions.  You can read about it here and get the code from here.

Also, I've also ported my Dojo version of the the Pipes framework into a Native version of Javascript.  I'll post on that shortly.

:)

UPDATE:  I posted version 1.0 of the Pipes PureMVC Native Javascript port.  You can read about it here.


Writing your PureMVC classes in the PureMVC define style and the view and service components in the Dojo style would certainly decouple the two and make the PureMVC parts reusable and self-consistent.

Consider the possibility of using more than one toolkit, each with different ways of building view components. Do you decide to write the whole app in one or the other of those styles, or do you let the MVC part of the app be in a common style, and the view components and service components in their own styles. The latter approach will let someone familiar with Toolkit A or B easily write view components in those styles (and be aided by online examples in those styles), while the MVC part allows PureMVC developers not familiar with Toolkit A or B still be able to apply their skills immediately to the application. It's a good way to distribute responsibility around a team and make the codebase flexible to change at the boundaries.

I'm not yet 100% certain what their concept of modules encompasses, but I'll look at it more.

And is there any desire to go native with Pipes?  
I was actually thinking about porting it recently, I just had a ton of other things going on. It would definitely be a good utility to have for the native port.

3  PureMVC Manifold / Demos and Utils / Re: Dojo AMD Implementation of PureMVC and Pipes on: October 09, 2012, 01:22:14
This is a tad long, so bear with me:

I use main.js to force Dojo's AMD loader to retrieve each file and make sure it is loaded prior to running any other code.

Dojo does let you declare a fully qualified name in the file that defines the class, but it goes in the second arg of the define() call that creates the returned object, and it uses periods instead of slashes, like this:

:
define(
    [
        "dojo/_base/declare",
        "org/puremvc/js/multicore/core/View",
        "org/puremvc/js/multicore/patterns/observer/Observer"
    ],
    function(declare, View, Observer) {
        var Controller =declare("org.puremvc.js.multicore.core.Controller",[ControllerSuperClass], { // <-- notice FQ name
         });

        return Controller;
});

So the first part of the define call tells Dojo's loader to load each file specified before calling the creation function that follows it.  Those paths can be relative or FQ.  In fact, the FQ name part is optional and is sometimes discouraged since some coders like to have the freedom to move files around and use relative path names to load their dependencies.  (I'm not one of those)

So by calling main.js first, I am assured that all the PureMVC files will be loaded and I can reference them in any code that follows.  I can reference them either using the FQ name, or by specifying the path in the define() call's first arg and then use the param passed to the creation function.

Just to clarify (since this can get a tad confusing):  Let's assume you have a class called TestClass that descends from BaseClass and assume this TestClass is used by a few other classes.  You define it like this:

:
define(
    [
        "dojo/_base/declare",
        "custom/BaseClass"  // <-- parent class which TestClass inherits from
    ],
    function(declare, BaseClass) {
        var TestClass = declare("custom.TestClass", BaseClass, {  // <-- FQ name and parent class (null if no parent)
            membervar1: null, 
            constructor: function(key) {
                console.log("custom.TestClass()");
                membervar1 = "";
            }
        });
        TestClass.STATIC_CONST = "static_value_is_declared here";
        return TestClass;
    }
);

To get a reference to custom.TestClass, you can use any of these methods:

1.  You can import it in the first arg of a define and reference it using the name specified in the second arg like this:
:
define(
    [
        "dojo/_base/declare",
        "custom/TestClass"  <-- /* by specifying the TestClass (complete with path) here, it is certain to be loaded when the function below is run */
    ],
    function(declare, TestClass) {
        var SomeOtherClass = declare("custom.SomeOtherClass", null, {
            constructor: function(key) {
                console.log("custom.SomeOtherClass()");
                var myTestClass = new TestClass(); // here I use the param of 'TestClass' to ref the
            }
        });
        return SomeOtherClass;
    }
);

2.  You can import it in the first arg of the define to make sure it is loaded and then reference it anywhere from that point on using the fully qualified name:

:
define(
    [
        "dojo/_base/declare",
        "custom/TestClass" 
    ],
    function(declare) { <-- /*notice this time, I did not put TestClass in the args the creation function */
        var SomeOtherClass = declare("custom.SomeOtherClass", null, {
            constructor: function(key) {
                console.log("custom.SomeOtherClass()");
                var myTestClass = new custom.TestClass(); // since I declared its fully qualified name when I defined it, I can still reference it
            }
        });
        return SomeOtherClass;
    }
);

3.  You can load it in some other file first (like I do in main.js) and then reference it by the FQ name as shown above (just without needing to give the path in the first part of the define() call).  This is a tad risky because you are assuming everything is loaded for you.  It will work, but if you go ahead declare it as required (by listing it in the first section), you are guaranteed it will be there and you can cut down on the use FQ names in the code which can be a little unsightly to read.

And yes, Dojo does have a layering process in the build scripts so you can combine everything into a single file.  I did not include that but I certain can if that is needed. 

Hope that helps :)

I saw that you use a main.js file to define classpaths. Doesn't Dojo allows to declare classpath independently in each JavaScript file like Require.js does?

Like this(example given with the Controller class):
:
define(
    "org/puremvc/js/multicore/core/Controller" //<-- I mean adding this line
    [
        "dojo/_base/declare",
        "org/puremvc/js/multicore/core/View",
        "org/puremvc/js/multicore/patterns/observer/Observer"
    ],
    function(declare, View, Observer) {
       

I found this way of doing things really neat, as it allows to use a simple concatenation/compression tool to create a single file for the whole PureMVC framework without having to be dependent on a specific tool. Are you using any compression tool (provided by the Dojo framework I suppose) that understands your syntax, or is this recommended by CommonJS?

I will probably use your work in my current project to speed up the way I will integrate PureMVC into Backbone+Require with full AMD support.
4  PureMVC Manifold / Demos and Utils / Re: Dojo AMD Implementation of PureMVC and Pipes on: October 09, 2012, 09:28:47
Yes, I agree.  There is definitely an issue with keeping things up to date; I actually ported this a while back (late 2011) while the other ports for Ext and Prototype were still considered viable and before the native implementation was considered to be the defacto way of using puremvc in javascript.  I just now got around to pushing it out for others to use if they needed it.  I wanted to take advantage of the AMD loader in Dojo (although for the puremvc code, it is of minimal performance gain), and since Pipes had not been implemented yet, I just ported everything over.

I really want to go with the native approach in the long-run.  The biggest issue now is that there are so few examples of how to use the native port within an application built with a library like Dojo.  I suspect that, to many javascript experts, the mixing of different OO/loader implementations is pretty obvious, but I'm a little confused about where the barrier between puremvc.define() ends and where dojo.define begins.  I would only want to use puremvc.define() for puremvc classes and then I would want to reference those within dojo-defined objects.  Any tips on the ideal way to integrate the two?  And is there any desire to go native with Pipes? 

 :) thanks
Bill

This was clearly a lot of work, and I can see how it is a tempting thing to do if you use Dojo. But the problem with writing ports that are dependent upon some other framework/toolkit, is that when the library you're basing your port upon changes, you have to play keep up. This happened when ExtJS 4 completely broke the old ExtJS 3 port. It left everyone dead in the water, unable to upgrade until someone had fixed the port.

Over the years it's become clear that people don't always want to continue maintaining ports after they've completed them. This is why we decided to drop the dependent ports from official inclusion in the project.
5  PureMVC Manifold / Demos and Utils / Dojo AMD Implementation of PureMVC and Pipes on: October 08, 2012, 04:40:25
If anyone needs a dojo version of puremvc that uses AMD loading, you can try the version I ported to work with with Dojo 1.7 with AMD loading.  I also ported the pipes utility which you can find in the utilities package.  I have not ported all the tests over yet, but the implementation seems to work well for my purposes.  I want to eventually use the native puremvc port with dojo but I haven't really figured out the details of how to do it cleanly yet.

 :)
Bill
6  Announcements and General Discussion / General Discussion / Multiple mediators for a single view? on: February 22, 2009, 02:22:15
I'm building a framework where the user creates a configuration file that defines how the Flex application is constructed.  One part of this framework allows the user to define a data visualization along with the components used in the construction.  Now I'm adding the ability to define and add filter logic so that once the visualization is created, it can be filtered dynamically at run-time.  I currently build the visualization from the configuration file and create/register mediators for the view components when the application starts.  For the filtering, I was thinking I could encapsulate the logic and functionality in a separate mediator that would point to a view that is already being mediated.    This would allow me to have one mediator manipulate the view's regular state, events, etc and then have another mediator handle the filtering notifications being applied.  Obviously, I could use one mediator to do both tasks but this means that my existing mediators have to be made even more complex with the addition of filtering behavior methods, etc.

So, does it make any sense to try to use more than one mediator for a single view if the functions being handled by each mediator on that view are clearly defined? 

Thanks
:)
7  Announcements and General Discussion / Architecture / Re: Proxy design question on: June 26, 2008, 09:22:41
Makes perfect sense now! Thanks   :)
8  Announcements and General Discussion / Architecture / Re: Proxy design question on: June 26, 2008, 08:32:39
Thanks for the reply Cliff.  I knew I could count on you  :)

Regarding approach #2, should I focus on making sure the linkage between the CombinedEventsProxy and the FlightEventsProxy/CalendarEventProxy goes in just one direction?  To clarify, should I have a reference to the CombinedEventsProxy inside of the FlightEventsProxy/CalendarEventProxy objects so they can call an update() method on the CombinedEventsProxy when their own contents are updated?   Or should I got the other direction, having the CombinedEventsProxy contain reference to FlightEventsProxy/CalendarEventProxy and just have it pull and combine their data arrays ondemand (when a call is made to CombinedEventsProxy.getCombinedEvents())?  Or are these both wrong?
9  Announcements and General Discussion / Architecture / Proxy design question on: June 25, 2008, 06:00:05
How do you handle the design of proxies when you have two classes that might also be combined into a single dataprovider? I've got an application that displays a calendar for pilots to use where they can enter 2 types of events:  FlightEvent and PersonalEvent.  These objects share a common set of properties based on a common interface that allows them to be both be displayed in the UI calendar.   Before the calendar displays them, they have to be placed into a single dataprovider/array.  However, I still need to be able to maintain each type of collection for adds/updates/deletes.   Which of these designs is best?

1.  Make one CombinedEventsProxy that maintains two internal arrays, one named flightEventsArray and one nameed personalEventsArray.   This proxy would also be responsible for providing the combined array as a property called combinedEventsArray which aggregates the two arrays into one.  I would also have the methods on this proxy to add/update/delete items of each time within their specific arrays and then update the CombinedEventsProxy accordingly.

2.  Make a FlightEventsProxy and a CalendarEventsProxy, each of which is responsible for their own types of events.  Then create a third CombinedEventsProxy that makes calls to FlightEventsProxy/CalendarEventsProxy in order to build the aggregated list of events that it will provide.  This approach seems a little better, but I'm not sure how to handle all the inter-proxy communication because I think I would need to have the CalendarEventsProxy call FlightEventsProxy/CalendarEventsProxy to initially build the combined list, but I would also need the FlightEventsProxy/CalendarEventsProxy to call the CombinedEventsProxy back to let it know that its contents need to be updated.  This coupling seems a little strong to me.

Any suggestions on how to handle this so I can get a combined view of all the events and still issues commands to CRUD each individual type of event?

Thanks
Pages: [1]