jeudi 26 février 2015

How to apply an mvc approach to the app.js file in a nodejs - express application

I've been following some nodejs - mongodb - express tutorials. I understand some of the basics such as the



  • the general principal of using app.js as a main (for want of a better term) controller for the site.


  • Storing all third party modules in their own node_modules directory.




  • Placing html/template engine files in views




  • Using the public directory as you might the skin folder in a php project




I'm trying to combine some of the things that I've come across in a lot of the tutorials and the one thing that is troubling me is how condensed the app.js folder is becoming. This breaking-up-the-app question is very similar to mine but I'm looking for a less subjective reply I think. The accepted answer suggests a method that he uses



~/app
|~controllers
| |-monkey.js
| |-zoo.js
|~models
| |-monkey.js
| |-zoo.js
|~views
| |~zoos
| |-new.jade
| |-_form.jade
|~test
| |~controllers
| |-zoo.js
| |~models
| |-zoo.js
|-index.js


I like how this looks and would like to implement something similar on my project.


For Example


I'm using the active-menu module and it seems to take up a lot of space in my app.js



//menu
var activeMenu = require('active-menu');
// Create a New Instance
var adminMenu = new activeMenu('adminMenu');
// Set HTML Attributes for the Top <ul> element
adminMenu.setAttributes({class : 'menu', id : 'admin-menu'});
// Home Node
var homeNode = adminMenu.addMenuNode('Home', '/');
homeNode.setAttributes({class : 'home home-icon', id : 'home-link'});

var postsNode = adminMenu.addMenuNode('About', '/about');
postsNode.setAttributes({class : 'about about-icon'});

var newPostNode = postsNode.addMenuNode('Contact', '/contact');
newPostNode.setAttributes({class : 'contact-post contact-icon'});

var app = express();

// Use Menu
app.use(adminMenu.menu);


I followed this tutorial to achieve that. It works so the tutorial served it's purpose but it would be better if inside my controller directory I could get the links dynamically somehow and just reference app.use(adminMenu.menu); so that it could be called in the layout.jade so how can I write this?


The same seems be the case for the http://ift.tt/1wlPMO0 etc. Based on this tutorial I came to have this also in my app.js file.



app.get('/:collection', function(req, res) {
var params = req.params;
collectionDriver.findAll(req.params.collection, function(error, objs) {
if (error) { res.send(400, error); }
else {
if (req.accepts('html')) {
res.render('data',{objects: objs, collection: req.params.collection});
} else {
res.set('Content-Type','application/json'); //G
res.send(200, objs); //H
}
}
});
});

app.get('/:collection/:entity', function(req, res) { //I
var params = req.params;
var entity = params.entity;
var collection = params.collection;
if (entity) {
collectionDriver.get(collection, entity, function(error, objs) {
if (error) { res.send(400, error); }
else { res.send(200, objs); } //K
});
} else {
res.send(400, {error: 'bad url', url: req.url});
}
});

app.post('/:collection', function(req, res) {
var object = req.body;
var collection = req.params.collection;
collectionDriver.save(collection, object, function(err,docs) {
if (err) { res.send(400, err); }
else { res.send(201, docs); } //B
});
});

app.put('/:collection/:entity', function(req, res) { //A
var params = req.params;
var entity = params.entity;
var collection = params.collection;
if (entity) {
collectionDriver.update(collection, req.body, entity, function(error, objs) { //B
if (error) { res.send(400, error); }
else { res.send(200, objs); } //C
});
} else {
var error = { "message" : "Cannot PUT a whole collection" };
res.send(400, error);
}
});

app.delete('/:collection/:entity', function(req, res) { //A
var params = req.params;
var entity = params.entity;
var collection = params.collection;
if (entity) {
collectionDriver.delete(collection, entity, function(error, objs) {
if (error) { res.send(400, error); }
else { res.send(200, objs); }
});
} else {
var error = { "message" : "Cannot DELETE a whole collection" };
res.send(400, error);
}
});


Again how can I write this so that these calls are in a model/controller and only seen by app.js when needed?


One objective that I am hoping to achieve through this question is an understanding of how to do this WITHOUT an additional framework.


Some reading that I did along my way before writing this question - Node Beginner - Nodejs with express, jade and stylus - Mongodb


Aucun commentaire:

Enregistrer un commentaire