sails.js 从控制器方法访问控制器方法
Posted
技术标签:
【中文标题】sails.js 从控制器方法访问控制器方法【英文标题】:sails.js access controller method from controller method 【发布时间】:2014-01-11 04:34:06 【问题描述】:为什么你不能从另一个控制器中访问其他控制器方法?
像这样。
module.exports =
findStore: ->
# do somthing
index: ->
@findStore(); # Error: undefined
编译
module.exports =
findStore: function() ,
index: function()
return this.findStore(); // Error: undefined
;
如果你不能做到这一点,那为什么不呢?我应该怎么做...
【问题讨论】:
你试过findStore()
或this.findStore()
吗?
是的,@findStore()
就是这样。我刚刚尝试过findStore();
...没有运气。
14 年后,您的问题的确切答案是因为您使用this
的位置超出了您的预期范围。如果你已经完成了var fs=findstore: function()
,然后从index:function
中调用了fs
,它应该可以工作。 . .我认为... 实用的、真实的世界 答案是来自@nidheeshdas
@monsto 是的,它会起作用,但它不是一回事,所以我无法在该文件之外使用它....
【参考方案1】:
过去几个小时遇到同样的问题。我使用了 api/services 文件夹。 它可能不是您所需要的,但它是一种选择。 一个很好的解释是here。 What services would one add to the api/services folder in sails.js
【讨论】:
您可以在我的回答中看到一个示例【参考方案2】:您可以使用sails.controllers.yourControllerName.findStore()
sails
全局对象引用了几乎所有内容。
【讨论】:
请注意,RabbitController
将被引用为 sails.controllers.rabbit.feed()
。
很棒的解决方案,对我来说效果很好,注意它区分大小写,IE Rabbit 不起作用,rabbit 可以。
另外值得注意的是,您可以通过sails.middleware.blueprints.create(req, res)
调用蓝图操作
还要注意,如果你有一个嵌套的控制器结构(例如控制器 -> v2 -> RabbitController.js),使用sails.controllers.rabbit.feed() 或sails.controllers.v2.rabbit。 feed() 不起作用。我不得不使用@lloop 建议的服务【参考方案3】:
当您只是想快速构建一些东西时,这有点烦人,但从长远来看,它会强制执行良好的代码组织实践(通过将所有业务逻辑推入控制器变得更加困难)。
【讨论】:
那不就是业务逻辑应该驻留的地方吗? 是的,但是对于大型项目,您不希望将控制器的所有业务逻辑代码放在一个文件中 是的,绝对不在一个文件中。 我一直将业务逻辑封装在自定义模块中(通常在服务中)......并根据需要要求它们。【参考方案4】:至少对我和我的团队而言,在 Sails 中组织代码的最佳方法之一是在服务 (/api/services) 中拥有所有真正的业务逻辑。可以从任何控制器全局访问这些对象。
此外,一个好的做法是在服务中使用 Promise(因为 Sails 在模型方法中使用它们)
只需使用您的代码创建一个商店服务 (StoreService.js):
module.exports =
findStore: function(storeId)
// here you call your models, add object security validation, etc...
return Store.findOne(storeId);
;
您的控制器应处理与请求、调用服务和返回适当响应相关的所有事情。
例如,在你的例子中,控制器可能有这个:
module.exports =
index: function(req, res)
if(req.param('id'))
StoreService.findStore(req.param('id'))
.then(res.ok)
.catch(res.serverError);
else
res.badRequest('Missing Store id');
,
findStore: function(req, res)
if(req.param('id'))
StoreService.findStore(req.param('id'))
.then(res.ok)
.catch(res.serverError);
else
res.badRequest('Missing Store id');
,
;
这样,您就拥有非常简单的控制器,并且所有业务逻辑都由服务管理。
【讨论】:
这里最受欢迎的帖子从字面上回答了这个问题,但这里的这篇帖子是一个实际的解决方案……它着眼于未来的组织来回答这个问题。这是这里存在的真正微妙的 XY 问题的 X 解决方案。 我分享的代码现在应该转换为async/await
,但它仍然是相关的。【参考方案5】:
解决这个问题的更优雅的方法是在函数名前使用关键字this
。
例子:
one: function()
console.log('First Function');
,
two: function()
// call the function one in the same controller
this.one();
【讨论】:
【参考方案6】:我想提出一个可行的解决方案,但不是最好的方法。我们可以使用 bind 函数将上下文与调用源绑定,如下所示:
generateUrl 存在于控制器 A 中
function generateUrl()
return 'www.google.com';
获取 URL 是控制器 A 中的另一种方法
getURL()
A.generateURL.bind(A.generateURL) //func call with optional arg
我希望这会有所帮助!
【讨论】:
【参考方案7】:你可以这样做:
//ArticleController
module.exports =
findStore: async () =>
return await findStoreFunc(req.param('id'));
,
index: async () =>
...
return await findStoreFunc(id);
;
const findStoreFunc = async (id) => ...
并使用另一个控制器的功能:
const ArticleController = require('./ArticleController');
//CustomerController
module.exports =
index: async () =>
...
let article = await ArticleController.findStore(id);
...
;
【讨论】:
以上是关于sails.js 从控制器方法访问控制器方法的主要内容,如果未能解决你的问题,请参考以下文章