當使用預設的視圖引擎 (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') %>
局部範本會自動繼承使用它們的任何地方可用的視圖區域變數。例如,如果您在名為 currentUser
的變數可用的視圖中調用 partial()
,那麼 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
以外的視圖引擎,請注意,對局部範本的支援 (有時稱為 "區塊"、"包含" 等) 可能包含也可能不包含,並且用法會有所不同。有關其語法和慣例的更多資訊,請參閱您選擇的視圖引擎的文件。