Подтвердить что ты не робот

Как создать глобальные переменные, доступные во всех представлениях, используя Express/Node.JS?

Хорошо, поэтому я создал блог с помощью Jekyll и вы можете определить переменные в файле _config.yml, которые доступны во всех шаблонах/макетах, В настоящее время я использую Node.JS/Express с EJS и ejs-locals (для частичных/макетов. Я ищу что-то похожее на глобальные переменные, такие как site.title, которые находятся в _config.yml, если кто-то знаком с Jekyll. У меня есть переменные, такие как название сайта (вместо названия страницы), имя автора/компании, которые остаются неизменными на всех моих страницах.

Вот пример того, что я делаю сейчас:

exports.index = function(req, res){
    res.render('index', { 
        siteTitle: 'My Website Title',
        pageTitle: 'The Root Splash Page',
        author: 'Cory Gross',
        description: 'My app description',
        indexSpecificData: someData
    });
};

exports.home = function (req, res) {
    res.render('home', {
        siteTitle: 'My Website Title',
        pageTitle: 'The Home Page',
        author: 'Cory Gross',
        description: 'My app description',
        homeSpecificData: someOtherData
    });
};

Я хотел бы иметь возможность определять переменные, такие как название моего сайта, описание, автор и т.д. в одном месте, и иметь их доступными в моих макетах/шаблонах через EJS без необходимости передавать их в качестве параметров для каждого вызова res.render, Есть ли способ сделать это и по-прежнему разрешать передавать другие переменные, специфичные для каждой страницы?

4b9b3361

Ответ 1

После того, как я смог изучить Справочник по API-интерфейсу Express 3, я обнаружил то, что искал. В частности, записи для app.locals а затем немного дальше по res.locals провели необходимые мне ответы.

Я сам обнаружил, что функция app.locals принимает объект и сохраняет все свои свойства в виде глобальных переменных, привязанных к приложению. Эти глобальные переменные передаются как локальные переменные для каждого представления. Функция res.locals, однако, привязана к запросу, и, таким образом, локальные переменные ответа доступны только для представлений, отображаемых во время этого конкретного запроса/ответа.

Так что для моего случая в моем приложении app.js я добавил:

app.locals({
    site: {
        title: 'ExpressBootstrapEJS',
        description: 'A boilerplate for a simple web application with a Node.JS and Express backend, with an EJS template with using Twitter Bootstrap.'
    },
    author: {
        name: 'Cory Gross',
        contact: '[email protected]'
    }
});

Затем все эти переменные доступны в моих представлениях как site.title, site.description, author.name, author.contact.

Я мог бы также определять локальные переменные для каждого ответа на запрос с res.locals или просто передавать переменные, такие как заголовок страницы, в качестве options параметров в вызове render.

EDIT: этот метод не позволит вам использовать эти локальные жители в вашем промежуточном программном обеспечении. Я на самом деле столкнулся с этим, как предлагает Pickels в комментарии ниже. В этом случае вам понадобится создать промежуточную функцию как таковую в его альтернативном (и оцененном) ответе. Функция промежуточного res.locals должна будет добавить их в res.locals для каждого ответа, а затем вызвать next. Эта промежуточная функция должна быть размещена над любым другим промежуточным программным обеспечением, которое должно использовать эти локальные жители.

EDIT: Другое отличие между объявлением locals через app.locals и res.locals заключается в том, что с помощью app.locals переменные устанавливаются один раз и сохраняются на протяжении всего срока действия приложения. Когда вы устанавливаете locals с res.locals в вашем промежуточном программном обеспечении, они устанавливаются каждый раз, когда вы получаете запрос. В основном вы предпочитаете устанавливать глобальные переменные через app.locals если значение не зависит от переменной req запроса, переданной в промежуточное программное обеспечение. Если значение не изменится, то будет более эффективным для его установки только один раз в app.locals.

Ответ 2

Вы можете сделать это, добавив их в объект locals в общем промежуточном программном обеспечении.

app.use(function (req, res, next) {
   res.locals = {
     siteTitle: "My Website Title",
     pageTitle: "The Home Page",
     author: "Cory Gross",
     description: "My app description",
   };
   next();
});

Локали - это также функция, которая расширяет объект locals, а не перезаписывает его. Таким образом, следующее работает также

res.locals({
  siteTitle: "My Website Title",
  pageTitle: "The Home Page",
  author: "Cory Gross",
  description: "My app description",
});

Полный пример

var app = express();

var middleware = {

    render: function (view) {
        return function (req, res, next) {
            res.render(view);
        }
    },

    globalLocals: function (req, res, next) {
        res.locals({ 
            siteTitle: "My Website Title",
            pageTitle: "The Root Splash Page",
            author: "Cory Gross",
            description: "My app description",
        });
        next();
    },

    index: function (req, res, next) {
        res.locals({
            indexSpecificData: someData
        });
        next();
    }

};


app.use(middleware.globalLocals);
app.get('/', middleware.index, middleware.render('home'));
app.get('/products', middleware.products, middleware.render('products'));

Я также добавил общее промежуточное ПО рендеринга. Таким образом, вам не нужно добавлять res.render для каждого маршрута, что означает, что у вас есть лучшее повторное использование кода. Как только вы спуститесь на многоразовый путь промежуточного программного обеспечения, вы заметите, что у вас будет много строительных блоков, которые значительно ускорят развитие.

Ответ 3

Для Express 4.0 я обнаружил, что использование переменных уровня приложения работает несколько иначе, и ответ Кори не работает для меня.

Из документов: http://expressjs.com/en/api.html#app.locals

Я обнаружил, что вы можете объявить глобальную переменную для приложения в

app.locals

например

app.locals.baseUrl = "http://www.google.com"

И затем в вашем приложении вы можете получить доступ к этим переменным, а в вашем явном промежуточном программном обеспечении вы можете получить к ним доступ в объекте req как

req.app.locals.baseUrl

например.

console.log(req.app.locals.baseUrl)
//prints out http://www.google.com

Ответ 4

В вашем приложении app.js вам нужно добавить что-то вроде этого

global.myvar = 100;

Теперь, во всех ваших файлах, которые вы хотите использовать эту переменную, вы можете просто получить к ней доступ как myvar

Ответ 5

Один из способов сделать это, обновив переменную app.locals для этого приложения в app.js

Установить через следующие

var app = express();
app.locals.appName = "DRC on FHIR";

Get/Access

app.listen(3000, function () {
    console.log('[' + app.locals.appName + '] => app listening on port 3001!');
});

Разработайте скриншот из примера @RamRovi с небольшим улучшением.

введите описание изображения здесь

Ответ 6

вы также можете использовать "глобальный"

Пример:

объявить следующее:

  app.use(function(req,res,next){
      global.site_url = req.headers.host;   // hostname = 'localhost:8080'
      next();
   });

Используйте следующее: в любых представлениях или файле ejs    <%        console.log(site_url);     % >

в js файлах    console.log(site_url);

Ответ 7

Что я делаю для того, чтобы избежать загрязненной глобальной области действия, это создать script, который я могу включить где угодно.

// my-script.js
const ActionsOverTime = require('@bigteam/node-aot').ActionsOverTime;
const config = require('../../config/config').actionsOverTime;
let aotInstance;

(function () {
  if (!aotInstance) {
    console.log('Create new aot instance');
    aotInstance = ActionsOverTime.createActionOverTimeEmitter(config);
  }
})();

exports = aotInstance;

Выполнение этого будет создавать только один экземпляр и делиться им, где бы он ни находился. Я не уверен, связано ли это с тем, что переменная кэшируется или из-за внутреннего механизма ссылки для приложения (который может включать кэширование). Любые комментарии о том, как node разрешает это, было бы замечательно.

Возможно, также прочитайте это, чтобы понять суть работы: http://fredkschott.com/post/2014/06/require-and-the-module-system/