简体   繁体   中英

How can I mount MVC nodejs + express

I have a nodejs + express project. I want to mount controller and view, but I dont know how.

In my app.js I have var stats = require('./controllers/stats'); and app.use(stats);

My folder controllers: stats/index.js and my views: stats/index.jade.

when I try to access localhost:1200/stats --> Cannot GET /stats

Are routes needed?

I use express"3.2.6"

My app.js

/**
 * Module dependencies.
 */

var express = require('express')
  , routes = require('./routes')
  , user = require('./routes/user')
  , http = require('http')
  , path = require('path');

var app = express();

//modulos
**var stats = require('./controllers/stats');**

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

// development only
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}

app.get('/', routes.index);
app.get('/users', user.list);

//rutas
**app.use(stats);**

var server = app.listen(1200);
console.log('Express server listening on port 1200');

In my controller

var express = require('express');
var app = module.exports = express();

app.set('views', __dirname + '/views');

app.get('/views/stats', function(request, response) {

  response.render('index', {
    title: 'Estamos en el controlador stats'
  });

});

In my view

extends layout

block content
  h1= title
  p Welcome to #{title}
  p esta es la vista del controlador Stats

Here's the complete solution. Since this is a valid question I faced long ago, I give you the whole code. But whether to understand it or not is left to you.

In app.js

var config = require('./config/config.js');
var express = require('express');
var app = express();
config.setConfig(app, express);

if (config.requestMethod == 'HTTPS') {
    var request = require('https');
    var options = [config.httpsOptions, app];
} else if(config.requestMethod == 'HTTP') {
    var request = require('http');
    var options = [app];
}

require('./config/db.js');

var server = request.createServer.apply(this, options).listen(app.get('port'), function() {
    console.log("Server started");
});

require('./route/router')(app);

In /config/config.js

var fs = require('fs');
module.exports = {
    port: 8443,
    mode: 'development',
    requestMethod: 'HTTP',
    httpsOptions: {
        key: fs.readFileSync('/etc/apache2/ssl/server.key'),
        cert: fs.readFileSync('/etc/apache2/ssl/server.crt'),
        requestCert: false,
        rejectUnauthorized: false
    },
    setConfig: function(app, express) {
        app.set('port', process.env.PORT || module.exports.port);   
        app.set('view engine', 'jade');
        app.use(express.favicon());
        //app.use(express.logger('dev'));
        app.use(express.json());
        app.use(express.urlencoded());
        app.use(express.methodOverride());
        app.use(app.router);
    }   
};

If it is HTTP only, you can remove HTTPS related options.

in /config/db.js

var mongo = require('mongoskin');

var MONGODB_HOST = "localhost";
var MONGODB_PORT = "27017";
var MONGODB_DATABSE = "dbname";
var MONGODB_USER_RW_NAME = "dbuser";
var MONGODB_USER_RW_PASS = "admin";

var db = mongo.db('mongodb://'+MONGODB_USER_RW_NAME+':'+MONGODB_USER_RW_PASS+'@'+MONGODB_HOST+':'+MONGODB_PORT+'/'+MONGODB_DATABSE, {safe: false});
var Tracking = require('../model/tracking.js');

GLOBAL.db = db;
GLOBAL.HOST = 'localhost';
GLOBAL.HEADER_MATCH = /localhost/i;
GLOBAL.ROOT_PATH = '/site/index.php/';
GLOBAL.Tracking = Tracking.construct(db);

Tracking is a custom model I wrote. You will see the code later.

In /route/router.js

router = function(app) {
    var routes = {
        'POST /test/link': 'testController.test'
    };

    var loadedControllers = {};
    for(var i in routes) {
        var requestMethod = i.split(' ')[0].toLowerCase();
        var routeURL = i.split(' ')[1];
        var controller = routes[i].split('.')[0];
        var method = routes[i].split('.')[1];
        if (loadedControllers[controller]) {
            var loadControl = loadedControllers[controller];
        } else {
            var loadControl = require('../controller/' + controller);
            loadedControllers[controller] = loadControl;
        }
        app[requestMethod](routeURL, loadControl[method]);
    }
};
module.exports = router;

As and when you add a new URL, or API, you need to add one entry in routes object linking URL to a controller.

In /controller/testController.js,

exports.test = function(req, res) {
    //Your code
};

In /model/Tracking/js,

exports.construct = function(db) {
    var _Tracking = function(data) {
        this.info = {
        _id: data && data._id || null,
        value: data.value || 0
    };

    _Tracking.test = function(id, cb) {
        //your code involving db
        cb(); //Send parameters to callback if necessary
        //Call this function from controller directly using Tracking.test
    };
    return _Tracking;
};

That's it. You can build on top of this.

First of all I need three folders in the root of my app.

models

views

controllers

Now on to the app.js

var express = require('express');
      ,http = require('http');
      ,path = require('path');
      ,app = express();
      ,fs = require('fs');

// database connection
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/mydb');

// some environment variables
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser('your secret here'));
app.use(express.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

// dynamically include routes (Controller)
fs.readdirSync('./controllers').forEach(function (file) {
  if(file.substr(-3) == '.js') {
      route = require('./controllers/' + file);
      route.controller(app);
  }
});

http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

Here is an example that I place in controllers/users.js

var mongoose = require('mongoose')
var Video = require('../models/user');
module.exports.controller = function(app) {

/**
 * a home page route
 */
  app.get('/signup', function(req, res) {
      // any logic goes here
      res.render('users/signup')
  });

/**
 * About page route
 */
  app.get('/login', function(req, res) {
      // any logic goes here
      res.render('users/login')
  });

}

res.render('users/signup') which results in the view being loaded from views/users/signup.jade in this app.

Finally, for reference, here is what the model in models/user.js may look like:

Var mongoose = require('mongoose')
      ,Schema = mongoose.Schema
      userSchema = new Schema( {
          username: String,
          password: String
      }),
User = mongoose.model('user', userSchema);

module.exports = User;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM