Вопрос

Я использую 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"
  }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top