Skip to content

other ways to create controllers

shimondoodkin edited this page Dec 4, 2010 · 11 revisions

This is crazy staff. what to know why? read on...

##option 1 - no magic + manual closure

var controller = require('controller.js').main(app);
controller.somefunction();

a controller with some function:

this.main=function(app)
{
 // code here
}

possible automation:

var controllers_to_load={
 controller1:'controller1.js',
 controller2:'controller2.js'
};

Object.keys(controllers_to_load).forEach(function(key){
 var controller_filename==controllers_to_load[key];
 app.controllers[key]=require('/some_path_folder/'+controller_filename).main(app);
})

app.controllers.controller1.somefunction();

##option 2 some convention to load all files from controllers folder by name.

app.controllers=[];
var fs=require('fs');
var path=require('path');
fs.readdir(path,function(files)
{
 files.forEach(function(file))
 {
  if(path.extname(file)=='.js')
  {
    app.controllers[file.substring(0,file.length-3)]=require('/some_path_folder/'+file).main(app);
    // or
    //app.controllers[file]= myrequire(file); ///myrequire could be whatever wrapping magic you like.
  }
 }
});
controllers.controller.somefunction();

i could digg the app.controllers object with recursive variable names with a function like this:

            //  inside 'obj' argument creates sub objects recursively by array of subnames but the last one,
            //  and returns the pre last object fererence;
            function deepname(obj,keys)
            {
             var subobj=obj,key;
             for(var j = 0; j < keys.length-1; j++)
             {
              key=keys[j];
              if(subobj[key]===undefined)
              {
                subobj[key]={};
              }
              subobj=subobj[key];
             }
             return subobj;
            }

            var filename="./folder/subfolder/controller.js"; // suppose a filename we have
            var controllers_dir=__dirname+'/controllers'; // no ending slash // define a folder of controllers.
            //validate filename path correctness like no double slashes or double dots or single dots.
            var filename2=fs.realpathSync(filename); // resolve the file name 
            filename2=filename2.substring(controllers_dir.length+1,filename2.length); // cut out text after controllers dir.
            filename_arr=filename2.split('/');
            var controller_parent=deepname(app.controllers,filename_arr);
            controller_name=filename_arr[filename_arr.length-1];
            controller_parent[controller_name]=myrequire(filename)

as a side thought i thought it could load all the app structure by convention by file extension.

##option 3 some convention + automatic closure magic to load all files from controllers folder by name.

and to add to the JavaScript file around a function like the one that used before.

this.main=function(app)
{
 // code here
}

##option 4 some convention + automatic closure magic + class magic + class filename convention all the above plus enable to use classes maybe also to make them global.

write the controller file as json: { getfoo:function(){ ... }, get bar:function(){ ... }, set bar:function(){ ... } }

it will be warped around by:

   //suppose the filename is like Foo-extends-Bar.js
   //I will use <??> to indicate a template variable.
   //suppose you got some classes framework.
   //
   this.main=function(app)     
    {
     global.<?=classname?>=Class.Create(<?=jsoncode?>,
     <?=extendsname?>);
    }

then execute it.

the class thing could be written in many different forms as you like. for example:

    this.main=function(app)
    {
      app.controllers.<?=classname?>=<?=jsoncode?>;
      app.controllers.<?=classname?>.prototype.__proto__=app.controllers.<?=extendsname?>;
    }

this function looks better.

and you got javascript templates...crazy staff...

to not mess with line numbers it is better do all in a one line: this.main=function(app){global.=classname?>=Create(=jsoncode?>, =extendsname?>); }

to execute a script you can use:

function runcode(evalcode,filename) 
{
 var Script = process.binding('evals').Script, scriptObj, i;
 scriptObj = new Script(evalcode, filename);
 scriptObj.runInThisContext();
 // maybe to do it not as a function simply in global scope with for statment
}

convention ideas

This document is in process. Everyone is encouraged to participate.

Additions and Comments are welcome in this page:

Comments:

also you can post an issue at https://github.com/shimondoodkin/nodejs-mongodb-app/issues

Philosophy for a framework, with practical examples:

  1. philosophy for a framework
  2. inter controller communication
  3. other ways to create controllers
  4. convention ideas