将对DB的引用传递到路由对我的Node / Express项目不起作用 [英] Passing reference to DB into routes is not working for my Node / Express project

查看:143
本文介绍了将对DB的引用传递到路由对我的Node / Express项目不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆