总述
Actions是Sails项目中对客户端响应请求的部分,它是model和view的中间层,负责梳理业务逻辑。
Actions是项目中的路由,当客户端请求一个URL时,将经由它执行逻辑并响应。
定义在何处
Actions通常定义在api/controllers目录下。
Actions示例
Actions文件通常有两种组织形式,actions2(推荐)和传统的。
Actions2:
module.exports = {
friendlyName: 'Welcome user',
description: 'Look up the specified user and welcome them, or redirect to a signup page if no user was found.',
inputs: {
userId: {
description: 'The ID of the user to look up.',
// By declaring a numeric example, Sails will automatically respond with `res.badRequest`
// if the `userId` parameter is not a number.
type: 'number',
// By making the `userId` parameter required, Sails will automatically respond with
// `res.badRequest` if it's left out.
required: true
}
},
exits: {
success: {
responseType: 'view',
viewTemplatePath: 'pages/welcome'
},
notFound: {
description: 'No user with the specified ID was found in the database.',
responseType: 'notFound'
}
},
fn: async function ({userId}) {
// Look up the user whose ID was specified in the request.
// Note that we don't have to validate that `userId` is a number;
// the machine runner does this for us and returns `badRequest`
// if validation fails.
var user = await User.findOne({ id: userId });
// If no user was found, respond "notFound" (like calling `res.notFound()`)
if (!user) { throw 'notFound'; }
// Display a personalized welcome view.
return {
name: user.name
};
}
};
使用传统的(req, res)方法来写actions会减少代码量,但使用actions2有如下好处:
- 代码不必依赖于req和res,使其更容易抽象成helper
- 可以及早确定actions需要的请求参数名和类型,在action运行时可以自动验证
- 不必仔细分析代码就能知道action所有可能的输出结果
传统:
module.exports = async function welcomeUser (req, res) {
// Get the `userId` parameter from the request.
// This could have been set on the querystring, in
// the request body, or as part of the URL used to
// make the request.
var userId = req.param('userId');
// If no `userId` was specified, or it wasn't a number, return an error.
if (!_.isNumeric(userId)) {
return res.badRequest(new Error('No user ID specified!'));
}
// Look up the user whose ID was specified in the request.
var user = await User.findOne({ id: userId });
// If no user was found, redirect to signup.
if (!user) {
return res.redirect('/signup' );
}
// Display the welcome view, setting the view variable
// named "name" to the value of the user's name.
return res.view('welcome', {name: user.name});
}
Controllers
生成Sails最快的方式就是把actions组织到controllers文件中。例如:
module.exports = {
login: function (req, res) { ... },
logout: function (req, res) { ... },
signup: function (req, res) { ... },
};
独立actions
对于大型成熟的系统,独立的actions可能是比controllers更好的方式。并非多个actions写在一个文件中,而是每个action都有一个独立的文件在api/controller目录下。如:
api/
controllers/
user/
login.js
logout.js
signup.js
保持“瘦”
和多数MVC框架一样,controller都是很瘦的一层。因为可重用的代码通常会被移到helpers或者提取到modules中。这使得项目变复杂的过程中更容易维护。
有一个规则:当使用同样代码的地方达到3处,即可将其移入helper中。