【问题标题】:How do I call one controllers method in another controller in Node如何在 Node 的另一个控制器中调用一个控制器方法
【发布时间】:2016-07-05 13:20:05
【问题描述】:

所以我有一个控制器,其方法定义为

controller1.js

 router.get('/:id/:field', function(req,res){
   var regex = /action|protocol|ip|port|direction|dip|dport|signature/;
     if (regex.test(req.params.field)){
       get(req,res,function(r){
         var field = req.params.field;
         res.status(200).send(r[field]);
       });
     } else {
         res.status(404).send("Signature Field Does Not Exist");
     }
 });

 function get(req, res, cb){
   MongoClient.connect(url, function(err, db) {
     if (err){
       console.error("Could not connect to database: %s",err);
       res.sendStatus(500);
     } else {
         var _id = req.params.id
         var collection = db.collection("signatures");
         var uniqueID = {"_id":_id};
         var cursor = collection.find(uniqueID); 
         cursor.hasNext(function (err, r) {
           if (err) {console.log(err);}
           else {
             cursor.next(function(err,r) {
               if (r == null){
                 res.status(404).send("Signature not found");
               } else {
                   cb(r);
                   db.close();
               }
             });    
           }    
         });
     }
   });
 }
module.exports = router

这在它自己的类中运行良好,我可以通过 localhost 从外部调用它。我希望能够在另一个控制器中使用这两者。所以在另一个文件中

controller2.js

var controller1 = require("./controller1.js");
router.get('/', function(req,res){
  controller1.get(req,res,cb(r){
      res.status(200).send(r);
  });
});

当我尝试在 controller2.js 中调用 get 时出现错误:Route.get() 需要回调函数,但得到了一个 [object Object]。我确信这不是数据库错误或任何类型的连接错误,只是从控制器 2 调用控制器 1 函数时出现的错误。我尝试将控制器 1 中的标头更改为

router.get = function(req,res,cb){
    ....
});

这使得controller1中的get无法调用该函数。

【问题讨论】:

    标签: javascript node.js express


    【解决方案1】:

    要保留您的代码DRY,您可以将所有重复功能保留在帮助模块中。

    结构可以是这样的:

    controllers  
    ├── helpers  
        └── index.js  
    ├── controller1.js   
    └── controller2.js  
    

    在“index.js”帮助模块中,你可以像这样包含你的函数:

    exports.yourFunction = function(args){
    ...
    };
    

    您可以像这样在控制器中调用它:

    var helpers = require("./helpers");
    ...
    helpers.yourFunction();
    

    此外,您可以在此线程中找到其他相关答案:

    Javascript - Best way to structure helpers functions in NodeJS

    【讨论】:

      【解决方案2】:

      如果你仍然想遵循这种方法,解决方案是:

      router.get('/:id/:field', function(req,res){
         var regex = /action|protocol|ip|port|direction|dip|dport|signature/;
           if (regex.test(req.params.field)){
             get(req,res,function(r){
               var field = req.params.field;
               res.status(200).send(r[field]);
             });
           } else {
               res.status(404).send("Signature Field Does Not Exist");
           }
       });
      
       var get=function(req, res, cb){
         MongoClient.connect(url, function(err, db) {
           if (err){
             console.error("Could not connect to database: %s",err);
             res.sendStatus(500);
           } else {
               var _id = req.params.id
               var collection = db.collection("signatures");
               var uniqueID = {"_id":_id};
               var cursor = collection.find(uniqueID); 
               cursor.hasNext(function (err, r) {
                 if (err) {console.log(err);}
                 else {
                   cursor.next(function(err,r) {
                     if (r == null){
                       res.status(404).send("Signature not found");
                     } else {
                         cb(r);
                         db.close();
                     }
                   });    
                 }    
               });
           }
         });
       }
      module.exports.router = router
      module.exports.get = get
      
      
      In controller2
      var controller1 = require("./controller1.js");
      router.get('/', function(req,res){
        controller1.get(req,res,cb(r){
            res.status(200).send(r);
        });
      });
      will work
      

      只需相应地进行一些更改。 无论您需要路由器对象中的控制器1,只需将其转换为:

      require('./cotroller1').router
      

      【讨论】:

        【解决方案3】:
        var test = require("./test");
        ...
        test.myFun();
        

        【讨论】:

          【解决方案4】:

          从包含在另一个控制器中的一个控制器调用函数是一种代码异味/糟糕的设计决策/反模式。

          我的建议是,如果您需要重用/共享公共功能给两个或更多模块使用它,请创建第三个模块,您可以共享给您的控制器。

          谈到网络应用程序的良好组织/最佳实践,创建一个“服务”文件层,将与数据库和各种基础设施/外部服务对话。然后在您的控制器中,只需从这些服务模块导入和调用该函数,让控制器更专注于它们的本意:接收和响应请求。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-09-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-10-17
            • 2015-09-07
            相关资源
            最近更新 更多