你不能嵌套控制器调用,因为the res.view() method that you would call in each one of them is terminal。
这个方法是终端的,也就是说一般是最后一行代码
您的应用应该针对给定的请求运行
控制器不渲染视图,它们向客户端调用方法发送 http 响应,例如 res.view() 或 res.json()。
对于你所说的HeaderController,我猜内容是静态的,你应该把内容写在the layout。
关于 MenuController,我知道菜单可能会根据请求而改变,您不一定要构建单页应用程序,并且您可能不想在页面完成后通过 AJAX 或 websocket 调用它加载。要以类似于您描述的方式解决它,您可以使用独立于控制器呈现视图的可能性。
您可以创建一个服务来执行它:
// api/service/partials.js
module.exports = {
/**
* Renders the menu and pass the result in a callback cb(err, html)
* The "req" argument is present like in a controller method, but not "res"
* "data" could be an optional argument to pass extra configuration
*/
menu: function(req, data, cb) {
// Write here the logic to build the menu depending on the request
// Access to the express app to render the "menu.ejs" template
// see http://expressjs.com/3x/api.html#app.render
sails.hooks.http.app.render('menu', data, cb);
}
};
要渲染的模板示例:
<!-- views/menu.ejs -->
This is the menu <%= data %>
此时,您可以简单地在所有控制器中调用 partials.menu(req, data, function(err, html) {}) 并将生成的 html 注入控制器的视图中。但这将是很多重复的代码。让我们写一个policy 来执行它:
// api/policies/dynamicMenu.js
module.exports = function(req, res, next) {
// Call the service that generate the content of the menu
// and inject the result in a "menu" variable accessible in the controller's template
partials.menu(req, {data: 'data test'}, function(err, html) {
res.locals.menu = html;
next();
});
};
您可以为每个“部分”编写一个策略(例如:一个用于菜单,另一个用于页脚......)。
将policy 应用于控制器:
// config/policies.js
module.exports.policies = {
// ...
// Apply the policy to controllers that display the menu
'aControllerThatDisplaysTheMenu': {
'*': ['dynamicMenu']
}
// ...
}
最后,在布局文件中显示菜单:
<!-- views/layout.ejs -->
...
<%= menu %>
...
这只是一个简单的示例,您必须处理错误并对其进行调整以更好地满足您的需求。