Доступ к локальным переменным Express.js на стороне клиента JavaScript

Любопытный, если я делаю это правильно, и если не так, как вы, ребята, подходите к этому.

У меня есть шаблон Jade, который должен отображать некоторые данные, извлеченные из базы данных MongoDB, и мне также нужно иметь доступ к этим данным внутри файла JavaScript на стороне клиента.

Я использую Express.js и отправляю данные в шаблон Jade следующим образом:

var myMongoDbObject = {name : 'stephen'};
res.render('home', { locals: { data : myMongoDbObject } });

Затем внутри home.jade я могу делать такие вещи, как:

p Hello #{data.name}!

Что выписывает:

Hello stephen!

Теперь то, что я хочу, также имеет доступ к этому объекту данных внутри JS файла на стороне клиента, чтобы я мог манипулировать объектом, скажем, щелчком кнопки перед отправкой его обратно на сервер для обновления базы данных.

Я смог выполнить это, сохранив объект "data" внутри скрытого поля ввода в шаблоне Jade, а затем извлекая значение этого поля внутри моего JS файла на стороне клиента.

Внутри home.jade

- local_data = JSON.stringify(data) // data coming in from Express.js
input(type='hidden', value=local_data)#myLocalDataObj

Затем в моем JS файле на стороне клиента я могу получить доступ к local_data следующим образом:

Внутри myLocalFile.js

var localObj = JSON.parse($("#myLocalDataObj").val());
console.log(localObj.name);

Однако этот трудный бизнес/разбирательство чувствует себя грязным. Я знаю, что могу привязывать значения объекта данных к объектам DOM в моем шаблоне Jade, а затем извлекать эти значения с помощью jQuery, но я хотел бы иметь доступ к фактическому объекту, возвращающемуся из Express в моей клиентской стороне JS.

Является ли мое решение оптимальным, как бы вы, ребята, это сделали?

Ответ 1

При выполнении рендеринга клиенту отправляется только обработанный HTML. Поэтому никаких переменных не будет. То, что вы могли бы сделать, вместо записи объекта во входном элементе выводит объект как визуализированный JavaScript:

script(type='text/javascript').
    var local_data =!{JSON.stringify(data)}

РЕДАКТИРОВАТЬ: По-видимому, Джейд требует точку после первой закрывающей круглой скобки.

Ответ 2

Я делаю это по-другому. В моем контоллере я делаю это:

res.render('search-directory', {
  title: 'My Title',
  place_urls: JSON.stringify(placeUrls),
});

И затем в javascript в моем файле jade я использую его вот так:

var placeUrls = !{place_urls};

В этом примере он использовался для плагинов типа twart bootstrap. Затем вы можете использовать что-то подобное, чтобы проанализировать его, если вам нужно:

jQuery.parseJSON( placeUrls );

Обратите внимание, что вы можете оставить локали: {}.

Ответ 3

Вы слышали о socket.io? (Http://socket.io/). Простым способом доступа к объекту из выражения было открытие сокета между node.js и вашим javascript. Таким образом, данные можно легко передать на клиентскую сторону, а затем легко манипулировать с помощью javascript. Код не должен быть большим, просто socket.emit() от node.js и a socket.on() от клиента. Я думаю, что это будет эффективное решение!

Ответ 4

Использование шаблона Jade:

Если вы вставляете фрагмент @Amberlamps кода над включенным статическим HTML файлом, не забудьте указать !!! 5 наверху, чтобы не сломаться ваш стиль, в views/index.jade:

!!! 5
script(type='text/javascript')
    var local_data =!{JSON.stringify(data)}

include ../www/index.html

Это будет передаваться в вашей переменной local_data до того, как будет загружена фактическая статическая HTML-страница, чтобы эта переменная была доступна глобально с самого начала.

Serverside (с помощью Jade templating engine) - server.js:

app.set('views', __dirname + '/views');
app.set('view engine', 'jade');

app.get('/', ensureAuthenticated, function(request, response){
    response.render('index', { data: {currentUser: request.user.id} });
});

app.use(express.static(__dirname + '/www'));

Ответ 5

Вам не нужно передавать переменные locals в вызове рендеринга, переменные locals - глобальные. В вызове файла мошенника не выставляйте выражения ключей, например, #{}. Просто используйте что-то вроде: base(href=base.url)

где base.url есть app.locals.base = { url:'/' };