I am a Java programmer porting a Java SE/Swing app to a web app. I've been experimenting with node.js and express.js for the client-facing app.
I would like to define functions at the node.js app level and have the methods and properties available to views in the node app. I'm primarily concerned about data modeling. I'd like to define the data models at the app level, and have the views have access to properties and methods of the models.
I have investigated the express.js and node.js docs, and it appears to me that includes ('require' s) can be done at the app level but that they do not propogate to the view level.
Am I missing something? Perhaps it's something fundamental about JavaScript or Node that I don't get...
Note that expressjs is not really a MVC framework, and thus, it's concept of "routes", "app", and "views" are pretty loose and designed to be unopinionated and changed easily.
That said, an expressjs view is usually simply an HTML template (powered by EJS or Handlebars) provided by the router/controller and given a Javascript object to fill itself with. Many Javascript templating engines describe themselves as "logic-less templates". Because of this, there is a lack of functions/classes (note that Node/Javascript does not even really have a concept of classes). A suggestion might be to add a level of indirection in which you have a script that takes your model and packs it into some standard object format that all your templates know about.
Something also to note:
A require
call in Node might be most akin to referencing a static Java class. (If I can find the reference I'm thinking of, I'll add it, but basically Node loads each script once and then returns the loaded copy for each subsequent require
call. EDIT: here it is, node.Module source code)
EDIT: Some example for a mapping script
Note that there aren't very strong patterns in Node so far, so people seem to be doing what makes sense to them. This example is by no means the "standard" Node practice.
model-view.js
module.exports.map = function(birthyear) {
return {
"birthYear": birthYear,
"age": getAge(birthYear)
}
}
//some function on the "view"
function getAge(birthYear) {
return (new Date()).getFullYear() - birthYear;
}
app.js
var transform = require('./model-transform');
app.get('/age/:user', function(req, res) {
db.doSomeDatabaseRequestToGetTheUsersBirthYear(req.params.user, function(birthYear) {
res.render('index', transform.map(birthYear));
});
});
Template (I like mustache-based templates, but you can use whatever)
<html>
<body>
You were born in {{ birthYear }}<br>
You are probably {{ age }} years old.
</body>
</html>