6

开始学习node.js和backbone.js,并使用TodoMVC示例作为我的指南。有几个部分我有麻烦缠绕我的头。见下文。了解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"); 

继承人是./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)); 

所以我的问题是,如何在猫鼬的 '待办事项' 模式.model('Todo')在此范围内可用的路线模块中?我看到模型模块正在导出mongoose.model('Todo',TodoSchema);所以我必须相信这是路由模块如何访问它,但我不知道为什么。我错过了什么?我有一种感觉,就是在这种情况下它不完全理解范围。另外,我不确定让路由功能匿名的原因。

非常感谢!

回答

8

这是比较令人困惑的事情要处理的节点和猫鼬开始出来的时候有一个。

当您第一次使用require('mongoose')时,它会创建一个singleton Mongoose实例 - 每次您需要时都会返回同一个实例。

这使得它可以很容易的工作,但它是一个有点“神奇”这就是开头难明白。

这意味着,当你调用app.js mongoose.connect("127.0.0.1", "todomvc", 27017);,它创建与应用程序持续的连接。

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

这是怎么得到的Todo模型到您的routes.js,和一个很好的理由,以确保告诉猫鼬你的模型是你在你的应用程序做的第一件事情之一。

要回答你关于理解范围的问题;您require的每个文件都有其自己的作用域,并且除访问全局对象(如进程)外无权访问任何文件。你必须require你要使用一切,只能通过调用函数或创建经由exports对象公开课传递变量英寸

因此对于实际的例子上面有出口从models.js的模式,因为它不是随后在应用程序中引用没有任何好处。在需要models.js的。这是一个在routes.js这些线路,使提供的藤堂模型:在包裹

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

但也没有好处(据我所知):

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

这就是藤上的这条线是如何存在因为这主要由require提供。

+0

非常感谢!这清理了很多。但是,如果我注释掉'module.exports = mongoose.model(“藤”,TodoSchema);'在models.js,应用程序失败说“架构尚未注册模式‘待办事项’”难道这是为了将来需要猫鼬而需要的吗? –

+0

对不起,更清晰,你需要'mongoose.model(“藤”,TodoSchema')'的一部分。这就是用猫鼬注册模型并使其随后可用的那一点。我的意思是你可以跳过'module.exports ='部分,因为你没有使用你正在导出的内容。此外,你会想用'exports.todoModel = ...'如果你想更多的车型添加到.js文件并导出所有的人,看到http://stackoverflow.com/questions/5311334/what-is - 目的 - nodejs-module-exports-how-do-you-use-it/12907839#12907839关于从模块导出的更多信息。 –

+0

太棒了!谢谢你的回答!这清理了很多。 –

0

你会想看看快车。

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

很多你复制的内容并粘贴使用快速脚手架 - 所以它的很多已经预先构建了你,你可以点击此处查看:http://expressjs.com/

我希望你分的权方向。