Доступ к локальным переменным 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-файла на стороне клиента, чтобы я мог манипулировать объектом, скажем, нажатием кнопки, прежде чем отправить его обратно на сервер для обновления базы данных.

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

Inside home.jade

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

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

Inside myLocalFile.js

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

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

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

Ответы на вопрос(5)

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

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

Решение Вопроса

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

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

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

Использование шаблонов 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-страницы, так что переменная будет доступна глобально с самого начала.

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

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

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

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

var placeUrls = !{place_urls};

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

jQuery.parseJSON( placeUrls );

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

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

Ваш ответ на вопрос