Доступ к локальным переменным 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:'/' };