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] 2
Print
Author Topic: Give us feedback on the native port's simple 'class inheritance' facility  (Read 34175 times)
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« on: January 23, 2012, 05:35:21 »

The Native JS port will include an optional function for emulating class inheritance. You'll be able to use this method to define your PureMVC subclasses (which make up most of your application aside from the view components).

The benefits of using this method would be that your PureMVC code would not be tied to your UI framework which probably does your class emulation as well. It gives you a shorthand way of emulating classes if you don't want to use a third-party lib for that. But you could use pure JS to do it yourself (as the framework will do internally, or a third-party lib for creating classes if you'd really rather go that way.

A fictitious example would be:

:
puremvc.define (

        // class info- defined separately to avoid collision with property
        // names defined on the prototype. None of these properties are added
        // to the classes produced.
        {
            /**
             * The classlets qualified name. The framework will automatically
             * create this object hierarchy for you, and your classes
             * constructor will be its referent
             *
             * @type {String}
             */

            classname: 'example.UserMediator'

            /**
             * The classlets superclass. The helper method will take care
             * of subclassing your class. Optional.
             *
             * @type {Function}
             */
        ,   parent: puremvc.Mediator

            /**
             * Your classes constructor. If not provided, one will be created
             * automatically for you. The automatically created constructor will
             * take care of invoking super constructors if the class is
             * extended from another
             *
             * @constructor
             */
        ,   constructor: function (viewComponent)
            {
                puremvc.Mediator.call(this.constructor.NAME, viewComponent);
            }
        }

        // prototypal traits- all instances will have these properties and
        // you can override superclass methods
    ,   {
            /** @override */
            listNotificationInterests: function ()
            {
                return [   ];
            }

            /** @override */
        ,   onRegister: function ()
            {
            }

            /** @override */
        ,   onRemove: function ()
            {
            }

            /**
             * Get the UserMediators UiComponent
             * @return {User}
             */
        ,   getUser: function ()
            {
                return this.viewComponent;
            }
        }

    ,   // static traits, i.e. properties which will be defined on constructors
        {
            /**
             * @static
             * @const
             * @type {String}
             */
            NAME: 'UserMediator'
        }
    );

We're looking for input on a name for this function (remember, it'll have to be typed often so it should be short).

Some possibilities are bless, classlet, define, inherit.

Anyone have a better suggestion or a vote about one of these?

-=Cliff>
« Last Edit: January 23, 2012, 05:42:56 by puremvc » Logged
Tekool
Sr. Member
****
Posts: 192


View Profile WWW Email
« Reply #1 on: January 24, 2012, 09:28:10 »

Why not using no name at all for the creational method?
« Last Edit: January 24, 2012, 09:31:20 by Tekool » Logged
tolmark12
Newbie
*
Posts: 5


View Profile Email
« Reply #2 on: January 24, 2012, 09:36:21 »

define probably makes sense even though it's not a perfect fit. bless is kind of fun though probably not immediately clear what the purpose of the method is.

Actually I kind of like:
wake

Maybe a few others:
endow
extend
activate
activateMvcPowers :-)
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #3 on: January 24, 2012, 11:35:39 »

@Tekool

Why not using no name at all for the creational method?
How would that work?

@tolmark12
activateMvcPowers

Good one.

wake() is good too, but like bless() might not be immediately obvious. Bless has a little precedent (it is the Perl way to "bless a in object into a class").

extend() is probably best. We've been trying to avoid making overt OOP references because it has a lot of baggage that aren't necessarily applicable to JS, which has no classes.

Whatever it is, needs to be short, and IMO not be widely used in other JS libs, since it could potentially cause confusion over its origin and what it is supposed to do.

-=Cliff>
« Last Edit: January 24, 2012, 02:11:54 by puremvc » Logged
tolmark12
Newbie
*
Posts: 5


View Profile Email
« Reply #4 on: January 24, 2012, 12:54:27 »

extend would definitely be my preference, especially when you understand the context that puremvc is extending the class. The only danger is it could look like puremvc is extending itself nevertheless, my vote would be for extend.
Logged
Tekool
Sr. Member
****
Posts: 192


View Profile WWW Email
« Reply #5 on: January 24, 2012, 02:42:21 »

How would that work?

I'm sorry to talk about it again, but I'm using this syntax in Objs. In this case puremvc would not be a constructor but only a simple method.

In our case the syntax would simply be :
:
puremvc(

        // class info- defined separately to avoid collision with property
        // names defined on the prototype. None of these properties are added
        // to the classes produced.
        {
            /**
             * The classlets qualified name. The framework will automatically
             * create this object hierarchy for you, and your classes
             * constructor will be its referent
             *
             * @type {String}
             */

            classname: 'example.UserMediator'

            /**
             * The classlets superclass. The helper method will take care
             * of subclassing your class. Optional.
             *
             * @type {Function}
             */
        ,   parent: puremvc.Mediator

            /**
             * Your classes constructor. If not provided, one will be created
             * automatically for you. The automatically created constructor will
             * take care of invoking super constructors if the class is
             * extended from another
             *
             * @constructor
             */
        ,   constructor: function (viewComponent)
            {
                puremvc.Mediator.call(this.constructor.NAME, viewComponent);
            }
        }

        // prototypal traits- all instances will have these properties and
        // you can override superclass methods
    ,   {
            /** @override */
            listNotificationInterests: function ()
            {
                return [   ];
            }
        }

    ,   // static traits, i.e. properties which will be defined on constructors
        {
            /**
             * @static
             * @const
             * @type {String}
             */
            NAME: 'UserMediator'
        }
    );


If David finally chose that we need to use the method to reach classes identified by their namespace, we just need to identify the type of the parameter passed to the function to know if it's a class that is declared or a namespace that we want to reach. We can think of it as an overload like Java does. It would so be with :
:
var MyClassObject = puremvc("example.UserMediator");
This is simple and lightweight.
« Last Edit: January 24, 2012, 03:35:13 by Tekool » Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #6 on: February 05, 2012, 03:50:35 »

BTW, after all, this ended up as puremvc.define(). There were lots of suggestions, but in the end, the fact that enough other frameworks use define for this purpose and it makes sense. I do like the shortened puremvc("example.UserMediator") syntax, but what it does is sort of unclear.

-=Cliff>
Logged
zermattchris
Full Member
***
Posts: 35


View Profile Email
« Reply #7 on: February 08, 2012, 11:07:11 »

I think define is fine

Just to check - is someone working on a super-simple Hello World example yet? I'm not clever enough to figure it out on my own...  :o

-Chris
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #8 on: February 08, 2012, 03:31:54 »

is someone working on a super-simple Hello World example yet?
Not yet, but I plan to have a go with it myself very soon. I've just put up several EmployeeAdmin demos in JS (using the Native port and ExtJS, but the classes are ExtJS style, not using puremvc.define(). I'm hoping to find that it isn't hard to port those over to Native style, but we'll see. I still have to get the BoxSplash Native/ExtJS demos posted properly first.

-=Cliff>
Logged
benjiaminid
Newbie
*
Posts: 1


View Profile Email
« Reply #9 on: May 20, 2012, 11:04:50 »

Hello there,
pureMVC for javascript is great, but when is coming to inheritance the 'super' call is missing when overiding a method. This is a must have when the project is getting a little bigger.
As a solution would be great if someone can change the way puremvc defines a class in "oop.js" with this method http://ejohn.org/blog/simple-javascript-inheritance/ which is quite used.

Thank you, and keep the good work.
Logged
jrmorrill
Newbie
*
Posts: 6


View Profile Email
« Reply #10 on: November 03, 2012, 12:58:11 »

I too ran into the same issue as benjiaminid. When overriding a method, I wanted/needed to be able to call the parent method. In AS3 this is accomplished by using the super keyword when inside a overridden method.

PrototypeJS allows me to do something similar with the $super keyword, so I decided to adjust the native port to support Prototype's implementation of inheritance. The only adjustment needed was to replace all of the strings ".constructor" with ".initialize". This allows for the default constructor to be found by PrototypeJS so that it can keep track of the super class.

Say, for example, I have a BaseMediator that is going to be extended by other mediators.

BaseMediator:
:
var BaseMediator = Class.create(
  puremvc.Mediator,
  {
    initialize: function($super, name, viewComponent)
    {
      $super(name, viewComponent);
    },
   
    listNotificationInterests: function()
    {
      return [
        ApplicationFacade.NOTIFICATION_A
      ];
    },
   
    handleNotification: function(notification)
    {
      switch(notification.getName()) {
        case ApplicationFacade.NOTIFICATION_A:
          // do stuff for A
          break;
      }
    }
  }
);

ExtendedMediator:
:
var ExtendedMediator = Class.create(
  BaseMediator,
  {
    initialize: function($super, name, viewComponent)
    {
      $super(name, viewComponent);
    },
   
    listNotificationInterests: function($super)
    {
      var interests = $super();
      interests.push(ApplicationFacade.NOTIFICATION_B);
      return interests;
    },
   
    handleNotification: function($super, notification)
    {
      switch(notification.getName()) {
        case ApplicationFacade.NOTIFICATION_B:
          // do stuff for B
          break;
        default:
          // let the super class handle it
          $super(notification);
          break;
      }
    }
  }
);
ExtendedMediator.NAME = "ExtendedMediator";

I'm sure there are other frameworks out there that allow you to do something similar, however, I'm most familiar with Prototype inheritance so it works for me.

Does anyone know if the NativePort is going to support something similar to the $super keyword ever?
Logged
Tekool
Sr. Member
****
Posts: 192


View Profile WWW Email
« Reply #11 on: November 03, 2012, 04:51:57 »

If you really can't refrain you to use Prototype.js $super(),  better to rewrite the PureMVC JavaScript code itself, I've made a PureMVC port to Prototype.js (with 1.6.1 syntax but it has to work with 1.7.1 or make me a pull request) : http://www.tekool.net/blog/2011/01/19/puremvc-port-to-prototype-javascript-framework/

Another solution is to use TypeScript/Haxe to write JavaScript. I'm working on the TypeScript port of PureMVC, it finally allows us to write JavaScript code using simple and static typed syntax like super(). It still need some polish but it works like a charm.

I don't know for David who is responsible of the project, but in my opinion we better have to keep the prototype chain syntax to stay easily portable with more frameworks and languages.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #12 on: November 04, 2012, 10:55:05 »

Also, there is a PureMVC Dart port. Dart has proper inheritance and typing.

But I see the problem here and I checked out John Resig's solution, which seems proper. I don't know what it would take to adapt it to the oop.js class, but its worth looking into.

-=Cliff>
Logged
Tekool
Sr. Member
****
Posts: 192


View Profile WWW Email
« Reply #13 on: November 04, 2012, 03:02:01 »

Also, there is a PureMVC Dart port. Dart has proper inheritance and typing.

Yep but tell me if I'm wrong, Dart's compiling to JavaScript is not really intended to be executed on the web. What is the status of Dart to JavaScript compiling? It seems to have been critized a lot by the past.

I checked out John Resig's solution, which seems proper. I don't know what it would take to adapt it to the oop.js class, but its worth looking into.

I can have a look into porting the John Resig solution into PureMVC. I have studied those kind of solution when working on Objs. Objs uses a system pretty near than the one from the John Resig solution (my solution is quite older than his, I'm kind of proud of it). In 2008 and before, it has one main caveat, it absolutely needs JavaScript to support the constructor keyword. Some old browsers doesn't support it (it even can cause serious issues with some Safari versions). But to be honnest today no one care, even TypeScript output an extend method that make use of constructor (I checked and PureMVC define even already use it).

From what I remember the idea of John Resig also can cause some issue with an inheritance chain where :

1) The SuperClass define a method.
2) The first subclass doesn't define this method.
3) The third subclass define this method and makes use of the super method.

From what I remember the call to super will not work where it has to, it has to be verified.

You may say...no one care, but the first implementation of this solution may break within PureMVC with the Notifier sendNotification method in any Mediator/Proxy/Command subclass.

If this is really something that may interest people I could work on it, I like those problematic a lot. ;)

As I told you recently I will work on the JavaScript port to transform the Employee Admin demo from Objs to define(). This could be a good occasion to try it so.

It may be a good idea to also port the standard version? What it is the status of this too?


« Last Edit: November 04, 2012, 03:11:03 by Tekool » Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #14 on: November 10, 2012, 03:20:17 »

can have a look into porting the John Resig solution into PureMVC. I have studied those kind of solution
That would be really great, I'd love to see it. The problem you outline with the ultimate superclass methods not being reachable if the intervening subclasses fail to override has to be handled, and I'm sure it will complicate matters quite a bit.

I've been working recently with getting Bill White's pipes port ready (moving to puremvc.pipes.* rather than org.puremvc.js.multicore.utilities.pipes.* and fixing bugs).  I ran into the inheritance problem there. And another issue is that the current documentation tool (jsduck) can't follow the PureMVC define() hierarchy. Therefore I've chosen to work with his native JS prototype version for the official repo.
Logged
Pages: [1] 2
Print