将对DB的引用传递到路由对我的Node / Express项目不起作用 [英] Passing reference to DB into routes is not working for my Node / Express project
问题描述
我正在使用node + express创建一个简单的REST API,并尝试将路由逻辑与数据库逻辑分开。我从路线中获取访问数据库时遇到问题。
I am using node + express to create a simple REST API, and am trying to separate out routing logic from db logic. I am having a problem getting access to the DB from the routes.
这是我的server.js代码:
Here is my server.js code:
var express = require('express')
, path = require('path')
, http = require('http')
, mongo = require('mongodb');
// Configure Express app
var app = express();
app.configure(function () {
app.set('port', process.env.PORT || 3000);
app.use(express.logger('dev')); /* 'default', 'short', 'tiny', 'dev' */
app.use(express.bodyParser()),
app.use(express.static(path.join(__dirname, 'public')));
});
// Configure DB
var Server = mongo.Server
, Db = mongo.Db
, BSON = mongo.BSONPure
, server = new Server('localhost', 27017, {auto_reconnect: true})
, db = new Db('mydb', server, {safe: true});
// Open DB to see if we need to populate with data
db.open(function(err, db) {
if(!err) {
console.log("Connected to 'mydb' database");
var Post = require('./routes/posts')
, post = new Post(db);
// Set the routes
app.get('/:org/posts', post.find);
app.get('/:org/posts/:id', post.get);
app.post('/:org/posts', post.add);
app.put('/:org/posts/:id', post.update);
app.delete('/:org/posts/:id', post.remove);
// Fire up the server
http.createServer(app).listen(app.get('port'), function () {
console.log("Express server listening on port " + app.get('port'));
});
}
});
这里是post.js文件中的逻辑:
and here is the logic in the post.js file:
var Post = function(db) {
this.db = db;
};
Post.prototype.get = function(req, res) {
var id = req.params.id;
var org = req.params.org;
var db = this.db;
console.log('Retrieving post: ' + id + ' from org: ' + org);
db.collection('ads', function(err, collection) {
collection.findOne({'_id':new BSON.ObjectID(id), 'org':org}, function(err, item) {
res.send(item);
});
});
};
Post.prototype.find = function(req, res) {
var org = req.params.org;
var db = this.db;
console.log('Finding posts for org: ' + org);
db.collection('posts', function(err, collection) {
collection.find({'org':org}).toArray(function(err, items) {
res.send(items);
});
});
};
Post.prototype.add = function(req, res) {
var org = req.params.org;
var post = req.body;
var db = this.db;
console.log('Adding post: ' + JSON.stringify(post) + ' for org: ' + org);
db.collection('posts', function(err, collection) {
collection.insert(post, {safe:true}, function(err, result) {
if (err) {
res.send({'error':'An error has occurred'});
} else {
console.log('Success: ' + JSON.stringify(result[0]));
res.send(result[0]);
}
});
});
};
Post.prototype.update = function(req, res) {
var id = req.params.id;
var org = req.params.org;
var post = req.body;
var db = this.db;
delete post._id;
console.log('Updating post: ' + id + ', org: ' + org);
console.log(JSON.stringify(post));
db.collection('posts', function(err, collection) {
collection.update({'_id':new BSON.ObjectID(id)}, post, {safe:true}, function(err, result) {
if (err) {
console.log('Error updating post: ' + err);
res.send({'error':'An error has occurred'});
} else {
console.log('' + result + ' document(s) updated');
res.send(post);
}
});
});
};
Post.prototype.remove = function(req, res) {
var id = req.params.id;
var org = req.params.org;
var db = this.db;
console.log('Deleting post: ' + id + ', org: ' + org);
db.collection('posts', function(err, collection) {
collection.remove({'_id':new BSON.ObjectID(id), 'org':org}, {safe:true}, function(err, result) {
if (err) {
res.send({'error':'An error has occurred - ' + err});
} else {
console.log('' + result + ' document(s) deleted');
res.send(req.body);
}
});
});
};
module.exports = Post;
我会认为post对象会保留db数据库引用以供调用时使用路线,但我得到以下错误:
I would think that the post object would hold on to the db reference for use when it is called from the routes, but I get the following error:
TypeError: Cannot call method 'collection' of undefined
at Post.find (../routes/posts.js:23:6)
任何人都可以指出我正确的方向?非常感谢
Can anyone point me in the right direction? Many thanks
推荐答案
您的帖子
$ c>这个在您正在注册的Express路由处理程序调用时,位于 Post
方法中。您需要 bind
您的 post
实例的方法,以便无论Express如何调用,这个
将是你的帖子
。像这样:
Your post
object is lost as the this
in your Post
methods when called by the Express route handlers you're registering. You need to bind
the methods to your post
instance so that no matter how they're called by Express, this
will be your post
. Like this:
// Set the routes
app.get('/:org/posts', post.find.bind(post));
app.get('/:org/posts/:id', post.get.bind(post));
app.post('/:org/posts', post.add.bind(post));
app.put('/:org/posts/:id', post.update.bind(post));
app.delete('/:org/posts/:id', post.remove.bind(post));
这篇关于将对DB的引用传递到路由对我的Node / Express项目不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!