Express.js Просмотр “глобальных данных”
-
12-10-2019 - |
Вопрос
Я использую Express.js (вкл. Node.js) и я знаю, что вы можете отобразить представление с пользовательскими данными с помощью параметра "locals".(res.render("template", { locals: { foo: "bar" } });
)
Есть ли какой-нибудь способ иметь "глобальные файлы"?(то есть.данные, доступные для каждого представления)
Я видел view options
, но это не рекурсивно, поэтому оно заменяет установленные мной локальные значения, если я использую какие-либо локальные значения в своем шаблоне.
Это мой вариант использования:Я хочу сделать так, чтобы файлы CSS / JS можно было добавлять отдельно для каждой страницы, и это является частью моего основного макета.Проблема в том, что если я явно не задаю эти массивы при каждом рендеринге, я получаю неопределенную ошибку, поэтому в моем шаблоне мне всегда приходится выполнять typeof css !== "undefined"
Танцы.Кроме того, у меня есть другие списки опций поля выбора, которые я не хочу явно добавлять в каждую из своих форм.
Решение
Стоит отметить для тех, кто, возможно, сталкивался с этим вопросом с момента выпуска Express 3, что метода 'dynamicHelpers' больше не существует.
Вместо этого вы можете использовать функцию app.locals, которая действует как объект, в котором вы можете хранить значения или функции, а затем делает их доступными для просмотров.Например:-
// In your app.js etc.
app.locals.title = "My App";
app.locals({
version: 3,
somefunction: function() {
return "function result";
}
});
// Then in your templates (shown here using a jade template)
=title
=version
=somefunction()
// Will output
My App
3
function result
Если вам нужен доступ к объекту запроса для извлечения информации, вы можете написать простую промежуточную функцию и использовать переменную app.settings.
Например, если вы используете connect-flash для отправки сообщений своим пользователям, вы могли бы сделать что-то вроде этого:
app.use(function(req, res, next) {
app.set('error', req.flash('error'));
next();
});
Что дало бы вам доступ к сообщению об ошибке с =settings.error в вашем шаблоне.
Эти темы рассматриваются здесь, хотя и несколько кратко: http://expressjs.com/api.html#app.locals
Обновить:Экспресс 4
app.locals
теперь это простой объект JavaScript, поэтому каждое свойство должно быть задано одно за другим.
app.locals.version = 3;
app.locals.somefunction = function() {
return "function result";
}
res.locals
предоставляет точно такую же функциональность, за исключением того, что ее следует использовать для данных, специфичных для запроса, а не для данных всего приложения.Пользовательский объект или настройки - это распространенный вариант использования.
res.locals.user = req.isAuthenticated() ? req.user : null;
res.locals.userSettings = {
backgroundColor: 'fff'
}
Другие советы
Существует способ иметь "глобальные" переменные для представлений, используя помощники динамического представления.
От Express.js руководство:
приложение.dynamicHelpers (obj)
Регистрирует помощников динамического просмотра.Помощники динамического представления - это просто функции, которые принимают запрос, разрешение и оцениваются на экземпляре сервера перед визуализацией представления.Возвращаемое значение этой функции становится локальной переменной, с которой она связана.
app.dynamicHelpers({ сеанс:функция (запрос, res){ возвращает запрос.session;} });
Все представления теперь будут иметь сеанс доступный, так что к данным сеанса можно будет получить доступ через session.name etc:
Вы можете найти реальный пример того, как их использовать, здесь: https://github.com/alessioalex/Nodetuts/tree/master/express_samples (узел app.js для запуска приложения)
Реальный пример использования параметров просмотра, как упомянул автор:
var app = express.createServer();
app.configure(function() {
app.set('views', path.join(__dirname, '..', 'views'));
app.set('view engine', 'jade');
app.set('view options', {
assetVersion: 1
});
А затем в моем макете. Джейд (базовый шаблон для приложения в моем случае):
link(rel='stylesheet', href='/static/css/' + assetVersion + '/style.css')
script(src='/static/js/' + assetVersion + '/script.js')
С этим маленьким трюком мне нужно только обновить assetVersion
Переменное одно место, чтобы убедиться, что мои активы не кэшируются в лаке или в других местах.
Я заглянул в исходный код, и на самом деле обнаружил, что теперь это возможно в никогда не в версиях Express. (Пока что доступно только через GitHub)
Самый простой способ сделать это - создать переменную, которая представляет набор местных жителей по умолчанию для ваших представлений. Затем создайте функцию, которая принимает объект, объединяет его с местными жителями и возвращает объединенный объект.
Я также Передайте всех моих местных жителей в контейнерном объекте т.е. {locals:{g:{prop:val}}}
Итак, в моих взглядах я могу ссылаться g.prop
который просто вернется null
Когда это не установлено, вместо того, чтобы бросить неопределенную ошибку.
function default_page_vars(custom_vars){
var vars = {
footer: true,
host: req.headers.host.split(':')[0],
config: this.config
};
if(custom_vars){
for(var k in custom_vars){
vars[k] = custom_vars[k];
}
}
return {
g:vars
};
}
//within your handler
response.render(view, {
locals: default_page_vars(other_locals)
});
Это похоронный ответ, но я наконец -то заставил его работать.
1) Это пример вокруг модуля подключение
2) Добавить кусок промежуточного программного обеспечения в Server.js/app.js, чтобы добавить req
к locals
. Анкет Это позволяет шаблону звонить request.flash()
Всякий раз, когда это нужно. Без этого flash()
потребляется по каждому запросу/перенаправление, побеждая цель.
var app = module.exports = express()
, flash=require('connect-flash');
app.configure(function(){
...
app.use(express.session({ secret: "shhh" }));
// Start Router
app.use(flash());
app.use(function(req, res, next) {
res.locals.request = req;
next();
});
app.use(app.router);
});
3) Установите свой маршрут как обычно (это CoffeeScript, но ничего особенного)
app.get '/home', (req, res) ->
req.flash "info", "this"
res.render "#{__dirname}/views/index"
4) Вызов request.flash () Когда вы хотите сообщения. Они потребляются по каждому звонку, так что не утешите.
!!!
html
head
title= config.appTitle
include partials/_styles
body
include partials/_scripts
#header
a(href="/logout") Logout CURRENTUSER
h2= config.appTitle
#messages
- var flash = request.flash()
each flashType in ['info','warn','error']
if flash[flashType]
p.flash(class=flashType)
= flash[flashType]
block content
h1 content here
Экспресс 4
Вы можете получить доступ к локальным переменным в шаблонах, отображаемых в приложении.
Таким образом, если вы хотите использовать какие -либо местные жители в своем шаблоне =>, предполагая, что у вас установлен NPM для шаблона двигателя для вашего приложения узла/экспресса.
Во -первых, вам нужно установить Экспресс местных объектов с вашими пользовательскими переменными в вашем app.js
Файл, вы можете использовать объект, если необходимо несколько значений (наш случай в этом посте)
/**
* Set locals object
*/
app.locals.layoutData = {
site: {
title: 'MyWebSiteTitle',
},
metaTag: {
charset: 'UTF-8',
description: 'MyDescription',
keywords: 'keyword-1,keyword-2,...',
author: 'MyName',
viewport: 'width=device-width, initial-scale=1.0'
}
};
Затем, чтобы получить доступ к значениям в файле шаблона layout.pug
(Например, в случае двигателя шаблона мопса)
doctype html
html
head
//title
title #{locals.layoutData.site.title}
//Describe metadata
meta(charset=layoutData.metaTag.charset)
meta(name='description', content=locals.layoutData.metaTag.description)
meta(name='keywords', content=locals.layoutData.metaTag.keywords)
meta(name='author', content=locals.layoutData.metaTag.author)
meta(name='viewport', content=locals.layoutData.metaTag.viewport)
body
block content
br
hr
footer
p All rights reserved © 2018 | #{locals.layoutData.site.title}
Протестировано с
"dependencies": {
"express": "^4.16.3",
"pug": "^2.0.3"
}