当使用默认的视图引擎 (ejs
) 时,Sails 支持使用局部视图(即“视图局部”)。局部视图基本上只是旨在从其他视图中使用的视图。
它们特别适用于在不同视图、布局甚至其他局部视图之间重复使用相同的标记。
<%- partial('./partials/navbar.ejs') %>
这将渲染位于 views/partials/navbar.ejs
的局部视图,它可能看起来像这样
<%
/**
* views/partials/navbar.ejs
*
* > Note: This EJS comment won't show up in the ejs served to the browser.
* > So you can be as verbose as you like. Just be careful not to inadvertently
* > type a percent sign followed by a greater-than sign (it'll bust you out of
* > the EJS block).
*
*/%>
<nav class="navbar">
<a href="/">Dashboard</a>
<a href="/inbox">Inbox</a>
</nav>
您作为第一个参数传递给 partial()
的目标路径应相对于您调用它的视图、布局或局部视图。因此,如果您从位于 views/pages/dashboard/user-profile.ejs
的视图文件中调用 partial()
,并且想要加载 views/partials/widget.ejs
,那么您将使用
<%- partial('../../partials/navbar.ejs') %>
局部视图会自动继承它们使用位置可用的视图局部变量。例如,如果您在视图中调用 partial()
,其中一个名为 currentUser
的变量可用,那么 currentUser
也将在局部视图中可用
<%
/**
* views/partials/navbar.ejs
*
* The navbar at the top of the page.
*
* @needs {Dictionary} currentUser
* @property {Boolean} isLoggedIn
* @property {String} username
*/%>
<nav class="navbar">
<div class="links">
<a href="/">Dashboard</a>
<a href="/inbox">Inbox</a>
</div>
<span class="login-or-signup"><%
// If the user accessing this page is logged in...
if (currentUser.isLoggedIn) {
%>
You are signed in as <a href="/<%= currentUser.username %>"><%= currentUser.username %></a>.
<%
}
// Otherwise the user accessing this page must be a visitor:
else {
%>
<a href="/login">Log in</a>
<%
}
%>
</span>
</nav>
视图局部变量的自动继承可以处理大多数局部视图的使用案例,但有时您可能想要传入额外的动态数据。例如,假设您的应用程序在几个不同的视图中都有以下代码的重复副本
<%
// A list representing the currently-logged in user's inbox.
%><ul class="message-list"><%
// Display each message, with a button to delete it.
_.each(messages, function (message) {
%><li class="inbox-message" data-id="<%= message.id %>">
<a href="/messages/<%= message.id %>"><%= message.subject %></a>
<button class="fa fa-trash" is="delete-btn"></button>
</li><% });
%></ul>
为了重构它,您可能会将 <li>
提取到局部视图中,以避免重复代码。但是,如果我们这样做,我们不能依赖自动继承。局部视图只会继承对调用它们的视图、局部视图或布局整体可用的局部变量,但此 <li>
依赖于一个名为 message
的变量,该变量来自对 _.each()
的调用。
幸运的是,Sails 还允许您将一个可选的字典(即一个普通的 JavaScript 对象)作为第二个参数传递给 partial()
<%- partial(relPathToPartial, optionalOverrides) %>
这些覆盖将在局部视图中作为局部变量访问,它们将优先于任何具有相同变量名的自动继承的局部变量。
这是我们上面示例的重构版本,它利用了这一点
<%
// A list representing the currently-logged in user's inbox.
%><ul class="message-list"><%
// Display each message, with a button to delete it.
_.each(messages, function (message) { %>
<%- partial ('../partials/inbox-message.ejs', { message: message }) %>
<% });
%></ul>
最后,这是我们新的代表单个收件箱消息的局部视图
/**
* views/partials/inbox-message.ejs
*
* An individual inbox message.
*
* @needs {Dictionary} message
* @property {Number} id
* @property {String} subject
*
*/%>
<li class="inbox-message" data-id="<%= message.id %>">
<a href="/messages/<%= message.id %>"><%= message.subject %></a>
<button class="fa fa-trash" is="delete-btn" aria-label="Delete"></button>
</li>
- 局部视图是同步渲染的,因此它们会阻止 Sails 为更多请求提供服务,直到它们完成加载。在开发应用程序时要牢记这一点,尤其是在预期大量连接的情况下。
- Sails 中对局部视图的内置支持仅适用于默认的视图引擎
ejs
。如果您决定自定义 Sails 安装并使用ejs
以外的视图引擎,那么请注意,对局部视图的支持(有时称为“块”、“包含”等)可能包含也可能不包含,并且用法将有所不同。有关其语法和约定的更多信息,请参考您选择的视图引擎的文档。