了解TodoMVC示例

时间:2012-10-24 01:31:53

标签: javascript node.js backbone.js model-view-controller todomvc

开始学习node.js和backbone.js,并使用TodoMVC示例作为我的向导。有几个部分我无法绕过头脑。见下文。

这是app.js.

var express = require('express')
  , http = require('http')
  , mongoose = require('mongoose')
  , models = require('./models')
  , routes = require('./routes')
  , app = express();

app.configure(function () {
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(require('stylus').middleware({ src: __dirname + '/public' }));
  app.use(express.static(__dirname + '/public'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
});

app.configure('development', function () {
  app.use(express.errorHandler());
});

routes.init(app);


mongoose.connect("127.0.0.1", "todomvc", 27017);

http.createServer(app).listen(3000);

console.log("Express server listening on port 3000");

Heres是./models:

var mongoose = require('mongoose'),

  TodoSchema = new mongoose.Schema({
    title: { 'type': String, 'default': 'empty todo...' },
    order: { 'type': Number },
    done: { 'type': Boolean, 'default': false }
  });

module.exports = mongoose.model('Todo', TodoSchema);

安迪终于来了,这是./routes:

(function (exports) {

  "use strict";

  var mongoose = require('mongoose')
    , crudUtils = require('../utils/crudUtils')
    , Todo = mongoose.model('Todo');

  function index(req, res) {
    res.render('index', { 'title': 'Backbone.js, Node.js, MongoDB Todos' });
  }

  exports.init = function (app) {
    app.get('/', index);
    crudUtils.initRoutesForModel({ 'app': app, 'model': Todo });
  };

}(exports));

所以我的问题是,在这个范围内,路由模块中的mongoose.model('Todo')中的'Todo'模型怎么样?我看到models模块正在导出mongoose.model('Todo',TodoSchema);所以我不得不相信路由模块可以访问它,但我不知道为什么。我错过了什么?我感觉它在这种情况下并不完全理解范围。此外,我不确定路由功能匿名的原因。

非常感谢!

2 个答案:

答案 0 :(得分:8)

这是在Node和Mongoose开始时要处理的更令人困惑的事情之一。

第一次require('mongoose')时,会创建一个singleton Mongoose实例 - 每次需要时都会返回相同的实例。

这使得它非常容易使用,但有点“神奇”,一开始很难理解。

这意味着当您在app.js中调用mongoose.connect("127.0.0.1", "todomvc", 27017);时,它会创建一个与应用持续存在的连接。

这也意味着mongoose.model('Todo', TodoSchema);使Todo模型可以在通过require('mongoose')调用mongoose.model('Todo')的任何其他范围内使用。这可以在您require的另一个文件的顶部变量,如上例所示,或者在回调过程中需要它的那一刻。

这就是你将Todo模型引入routes.js的方法,并且确保告诉Mongoose你的模型的一个很好的理由是你在应用程序中做的第一件事。

回答有关理解范围的问题;每个文件require实际上都有自己的作用域,除了像进程这样的全局对象之外,它们不能访问任何内容。您必须require要使用的所有内容,并且只能通过调用函数或创建通过exports对象公开的类来传递变量。

因此,对于上面的实际示例,从models.js导出模型没有任何好处,因为它随后未在应用程序中引用,其中需要models.js。在routes.js中的这些行使得Todo模型可用:

var mongoose = require('mongoose')
, Todo = mongoose.model('Todo'); // returns the Todo model that was registered by models.js

这就是Todo在这条线上的存在方式:

crudUtils.initRoutesForModel({ 'app': app, 'model': Todo });

在匿名函数中包装路由也没有任何好处(据我所知),因为这基本上由require提供。

答案 1 :(得分:0)

你想要查看Express。

  

Express是一个最小且灵活的node.js Web应用程序框架,为构建单页和多页以及混合Web应用程序提供了一组强大的功能。

您复制和粘贴的很多内容都是使用Express Scaffold - 所以很多都是为您预先构建的,您可以在此处查看:http://expressjs.com/

我希望指出你正确的方向。