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: Dojo AMD Implementation of PureMVC and Pipes  (Read 8706 times)
TripleToe
Newbie
*
Posts: 9


View Profile Email
« 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
Logged
Tekool
Moderator
Sr. Member
*****
Posts: 192


View Profile WWW Email
« Reply #1 on: October 09, 2012, 12:03:20 »

Many thanx for this work, this is an excellent idea!

This will help anyone working with PureMVC and any AMD compatible library, not only Dojo. I'm currently working with Backbone + Require it would help in using PureMVC here too.


If you want to finish the work on the Pipes (with tests etc.) I think that you must contact Cliff directly to push a new project on Github. I think you're the first to port Pipes in JavaScript.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #2 on: October 09, 2012, 07:30:08 »

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.
Logged
TripleToe
Newbie
*
Posts: 9


View Profile Email
« Reply #3 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.
Logged
Tekool
Moderator
Sr. Member
*****
Posts: 192


View Profile WWW Email
« Reply #4 on: October 09, 2012, 12:21:48 »

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.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #5 on: October 09, 2012, 01:19:39 »

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? 
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.
Logged
TripleToe
Newbie
*
Posts: 9


View Profile Email
« Reply #6 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.
Logged
Tekool
Moderator
Sr. Member
*****
Posts: 192


View Profile WWW Email
« Reply #7 on: October 10, 2012, 11:46:36 »

Indeed, you are right you're forced to use a main.js to order loading of each file. In fact my builds always use an XML file with Ant that order things for me before concate and compress them. I just forgotten that.

I'm using Backbone but with AMD too. If I need to use another compression solution that the one I use I will probably use near the same as yours, but using Require and its order plugin (I heard it is now included in Require directly).

Thanks for those infos.
Logged
TripleToe
Newbie
*
Posts: 9


View Profile Email
« Reply #8 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.

« Last Edit: October 18, 2012, 08:37:58 by TripleToe » Logged
Pages: [1]
Print