2017-01-18 52 views
0

我想重用我的控制器来处理数据库操作。我有点困难于构建我的应用程序。下面是我有:如何重用数据库控制器

server.js

var apiController = require('./controllers/api'); 

router.get('/cars', function (req, res) { 
    // get all cars from DB and render view 

    apiController.getCars().then(function (cars) { 
     res.render('index', {cars: cars}); 
    }); 
}); 

router.get('/api/cars', function (req, res) { 
    // get all cars from DB and return JSON 

    apiController.getCars().then(function (cars) { 
     res.json(cars); 
    }); 
}); 

控制器/ api.js

module.exports = { 

    getCars: function() { 
     db.collection('cars').find().toArray(function (err, cars) { 
      if (err) throw err; 
      return cars; 
     }); 
    }, 

    // tried also something like this but this doesn't really work 
    // for my use case because I don't want to attach any particular 
    // res to the function 
    getCars: function (req, res, next) { 
     db.collection('cars').find().toArray(function (err, cars) { 
      if (err) throw err; 
      res.json(cars); 
     }); 
    }, 
}; 

回答

0

您当前的问题是,你期望的承诺在server.js回报,同时你在控制器中使用回调。我建议你改变你的getCars函数来返回一个Promise。不知道你正在使用,但它可能看起来像这样的事情是什么ODM/ORM:

getCars: function() { 
    return db.collection('cars').find(); 
}, 
+0

感谢您的回答,您是对的,我期待server.js的承诺,这就是为什么它没有工作。使用承诺标准方式处理DB控制器 - 路由器关系中的表达?我基本上在寻找正确的模式,我不一定会遵守承诺。 – finspin

+0

这种方法的一个缺点是我不得不在每个路由器上对getCars进行错误处理,对吧? – finspin

+1

回调是在JavaScript中处理异步的旧方法。承诺新的。所以我建议你使用Promise,如果你不觉得太紧张的话。 –

0
server.js 

var apiController = require('./controllers/api'); 
    router.get('/cars', apiController.getCars); 



controllers/api.js 

    function getCarsAsync(req, res, next){ 
     db.collection('cars').find().then(function(carsData){ 
      if(carsData){ 
       return res.send(carsData); 
      } 
      else{ 
       return res.status(401).send('User is not authorized'); 
      } 
     }).catch(function(err){ 
      return next(err); 
     }); 
    } 

    module.exports = { 
     getCars: getCarsAsync 
    }; 
+0

您没有正确使用承诺。一个好的结构就是在module.exports中编写函数定义,如下所示: module.exports = {getCars:getCarsAsync} 并在getCarsAsync函数中写入所有逻辑 –

+0

如何使用此解决方案清理数据库中的错误消息?假设你想给一个400,如果你试图添加一个新的行到一个有独特的约束的表上?不会你的解决方案返回一般的500?我建议他的HttpStatus处理是在数据库函数之外完成的,因此可以重复使用 –

+1

@ R.Gulbrandsen实际上,您将有3至4种不同类型的错误代码。你可以做的是:使用'next'路由函数的第三个参数并配置express来有一个自定义的中间件来处理'next()'。然后你会传递错误信息为'next({“error”:“missing”,“description”:“一些错误信息”})中间件应该将映射丢失到404,因此api将得到404状态并显示相应的错误信息。 –

0

server.js

var apiController = require('./controllers/api'); 
router.get('/cars', function (req, res) { 
    apiController.get('cars').then(function (cars) { 
     res.render('index', {cars: cars}); 
    }); 
}); 

router.get('/api/cars', function (req, res) { 
    apiController.get('cars').then(function (cars) { 
     res.json(cars); 
    }); 
}); 

控制器/ api.js

var Promise = require('bluebird'); 
module.exports = { 
    get: function (modelName) { 
    return new Promise(function(resolve,reject){ 
     return db.collection(modelName).find().toArray(function(err, models){ 
     if (err) { 
      return reject(err); 
     } 
     else { 
      return resolve(models); 
     } 
     }); 
    }); 
    } 
}; 
相关问题