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


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

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

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

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

внутри дома.Джейд Я могу делать такие вещи, как:

p Hello #{data.name}!

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

Hello stephen!

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

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

внутри жилище.Джейд

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

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

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

5 64

5 ответов:

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

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

EDIT: по-видимому, Джейд требует точки после первой закрывающей скобки.

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

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

и затем в javascript в моем файле jade я использую его следующим образом:

var placeUrls = !{place_urls};

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

jQuery.parseJSON( placeUrls );

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

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

использование нефритовых шаблонов:

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

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

include ../www/index.html

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

серверная сторона (с использованием Jade templating engine) - сервер.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'));

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

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