2017-01-18 84 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); 
     } 
     }); 
    }); 
    } 
}; 
相關問題