Express.js Посмотреть "глобалы" - PullRequest
44 голосов
/ 18 января 2011

Я использую Express.js (на Node.js) и знаю, что вы можете визуализировать представление с пользовательскими данными с помощью параметра "locals".(res.render("template", { locals: { foo: "bar" } });)

Есть ли способ иметь "глобалы"?(т. е. данные, доступные каждому представлению)

Я видел view options, но это не рекурсивно, поэтому он заменяет локальные значения, которые я установил, если я использую какие-либо локальные объекты с моим шаблоном.* Это мой вариант использования: я хочу сделать так, чтобы CSS / JS-файлы могли быть добавлены для каждой страницы, и это является частью моего основного макета.Проблема в том, что если я не устанавливаю эти массивы явно при каждом рендере, я получаю неопределенную ошибку, поэтому в моем шаблоне мне всегда нужно танцевать typeof css !== "undefined".Кроме того, у меня есть другие списки опций блока выбора, которые мне не нужно явно добавлять в каждую из моих форм.

Ответы [ 7 ]

57 голосов
/ 13 октября 2012

Стоит отметить, что для тех, кто, возможно, сталкивался с этим вопросом после выпуска 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

Обновление: Express 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'
}
10 голосов
/ 16 июня 2011

Существует способ иметь "глобальные" переменные для представлений с помощью помощников динамического представления.

Из руководства Express.js:

app.dynamicHelpers (obj)

Регистрирует помощники динамического просмотра.Помощники динамического представления - это просто функции, которые принимают req, res и оцениваются по отношению к экземпляру сервера перед отображением представления.Возвращаемое значение этой функции становится локальной переменной, с которой она связана.

app.dynamicHelpers ({session: function (req, res) {return req.session;}});

Теперь у всех представлений будет доступен сеанс, так что к данным сеанса можно получить доступ через session.name и т. Д .:

Реальный пример их использования можно найти здесь: https://github.com/alessioalex/Nodetuts/tree/master/express_samples (узелapp.js для запуска приложения)

7 голосов
/ 25 декабря 2011

Реальный пример использования параметров просмотра, как упомянул автор:

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
  });

А затем в моем layout.jade (базовый шаблон для приложения в моем случае):

link(rel='stylesheet', href='/static/css/' + assetVersion + '/style.css')
script(src='/static/js/' + assetVersion + '/script.js')

С помощью этого небольшого трюка мне нужно только обновить переменную assetVersion в одном месте, чтобы убедиться, что мои активы не кэшируются в Varnish или других местах.

4 голосов
/ 20 января 2011

Я заглянул в исходный код и обнаружил, что это теперь возможно в никогда не версиях Express. (пока доступно только через GitHub)

1 голос
/ 19 января 2011

Самый простой способ сделать это - создать переменную, которая представляет набор локальных элементов по умолчанию для ваших представлений.Затем создайте функцию, которая принимает объект, объединяет его с локальными и возвращает объединенный объект.

Я также передаю ВСЕ мои локальные объекты в контейнерный объект , то есть {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)
});
0 голосов
/ 20 июня 2018

Экспресс 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 (например, в случае с механизмом шаблонов 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"
  }
0 голосов
/ 19 июня 2013

Это скрытый ответ, но я наконец-то получил его на работу.

1) Это пример модуля connect-flash

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 (), когда хотите получать сообщения. Они потребляются при каждом вызове, так что не используйте console.log, иначе они исчезнут: -)

!!!
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...