How to write reusable controllers code for dojox.mobile views

354 Views Asked by At

I'm writing an application based on dojox.mobile framework. I'm using dojo 1.9. Some views of the application are really similar and have a lot of things in common so I would like to create a general view and extend it to specialize it.

Given that every view has a controller, I tried to create a parent controller (which is a module defined via the define function) and then tried to extend it, but without success.

What I am doing is creating a GeneralController.js like the following:

define(["dojo/_base/declare",
        "dojo/_base/lang",
        "dojo/on"], 
    function(declare,lang, on){
        return declare("AppControllers/GeneralController",[],{
            init: function(){
                     //do something in GeneralController
            },

            beforeActivate: function(){
                     //...
            }
        })
    }
);

and a View1.js controller like the following:

define(["dojo/_base/declare",
        "dojo/_base/lang",
        "dojo/on",
        "AppControllers/GeneralController"], 
    function(declare,lang, on, general){
        return declare(general,{
            init: function(){
                     //do something in this View1.js controller
                     this.inherited();//do what was in general
            },

            beforeActivate: function(){
                     //...
            }
        })
    }
);

and in the config.json I have:

{
    //...
    "views":{
        //...
        "View1":{
           "template":"AppTemplates/View1.html",
           "controller":"AppControllers/View1.js"
        },
        //...
    }
    //...
}

The dojo.mobile framework seems not accept view controllers written as dojo class (via declare). How can I obtain a hierarchy of view controllers?

2

There are 2 best solutions below

0
On BEST ANSWER

It turns out that the best solution for me is to use dojox/app, as suggested by @tik27.

I was trying to extend the controller module associated to the view (see AppControllers/View1.js in the config below) but that module is simply mixed to the View. If I want to get a classy handling of the Views I can leverage the type property (see again the config json excerpt below).

config.json:

{
    //...
    "views":{
        //...
        "View1":{
           "template":"AppTemplates/View1.html",
           "controller":"AppControllers/View1.js"
           "type":"my/SpecializedView.js"
        },
        //...
    }
    //...
}

To do this I have to simply extend dojox/app/View in my my/GenericView which will contain custom properties and methods. Then I can write SpecializedViews extending my/GenericView:

my/GenericView.js

define([
    "dojo/_base/declare",
    "dojox/app/View"
], function(declare, View) {
    return declare("my/GenericView",[View], {
        customProp: "example", // Default content
        customMethod:function(){
            //do something
        }
    });
});

my/SpecializedView.js

define([
    "dojo/_base/declare",
    "my/GenericView"
], function(declare, GenericView) {
    return declare(GenericView, {
        init:function(){
            console.log(this.customProp);//will print "example"
        }
        customMethod:function(){
            this.inherited(arguments);//recall parent class' method
            //extend parent class' method
        }
    });
});

Anyway, the title of this question refers to dojox/mobile so you can find a fully dojox/mobile example il this jsfiddle http://jsfiddle.net/g00glen00b/5PCrb/ by @Dimitri M

3
On

Like @tik27 said, dojox/app might be your solution. However, we found that the documentation of the dojox/app section was lacking good examples so to lower the learning curve for other people, we made our own small framework (for dojox/mobile with IBM Worklight) which improves reusability.

We actually made a "base controller" module, extending dojox/mobile/View using a template like this:

define([
    "dojo/_base/declare",
    "dojox/mobile/View",
    "dijit/_TemplatedMixin"
], function(declare, View, TemplatedMixin) {
    return declare([View, TemplatedMixin], {
        templateString: "<header>My header</header> ${!content} <footer>footer</footer>", 
        content: null // Default content
    });
});

As you can see we have a standard template with a header and a footer, but we also use a placeholder called content. The general part of the template (in this case that header/footer) can you put here.

The view/controller modules extending this base controller look like this:

define([
    "dojo/_base/declare",
    "./ControllerMixin"
], function(declare, ControllerMixin) {
    return declare([ControllerMixin], {
        content: "This is the content"
    });
});

Because we enter the content property here, it will be placed at the position of the ${!content} we earlier defined.

If you need ot use widgets in your template you can also choose dijit/_WidgetsInTemplateMixin