Ответ 1
Я создал свою собственную небольшую промежуточную функцию, которая добавляет вспомогательный метод renderWithData
к объекту res
.
app.use(function (req, res, next) {
res.renderWithData = function (view, model, data) {
res.render(view, model, function (err, viewString) {
data.view = viewString;
res.json(data);
});
};
next();
});
Требуется имя вида, модель для представления и пользовательские данные, которые вы хотите отправить в браузер. Он вызывает res.render
, но передает функцию обратного вызова. Это дает команду express передать скомпилированную разметку вида на обратный вызов в виде строки, а не сразу же передать ее в ответ. Как только у меня есть строка представления, я добавляю его в объект данных как data.view
. Затем я использую res.json
для отправки объекта данных в браузер в комплекте с скомпилированным представлением:)
Edit:
Одно из предостережений с вышеизложенным заключается в том, что запрос должен быть сделан с помощью javascript, поэтому он не может быть полным запросом страницы. Вам нужен первоначальный запрос, чтобы вытащить главную страницу, содержащую javascript, который сделает запрос ajax.
Это отлично подходит для ситуаций, когда вы пытаетесь изменить URL-адрес и заголовок браузера, когда пользователь переходит на новую страницу через AJAX. Вы можете отправить частичный просмотр новой страницы обратно в браузер вместе с некоторыми данными для названия страницы. Тогда ваша клиентская сторона script может поместить частичный вид там, где он принадлежит на странице, обновить строку заголовка страницы и, при необходимости, обновить URL.
Если вы хотите отправить полностью полный HTML-документ в браузер вместе с некоторыми исходными данными JavaScript, вам необходимо скомпилировать этот код JavaScript в самом представлении. Это определенно возможно сделать, но я никогда не нашел способ, который не связан с некоторой магией строк.
Например:
// controller.js
var someData = { message: 'hi' };
res.render('someView', { data: JSON.stringify(someData) });
// someView.jade
script.
var someData = !{data};
Примечание: !{data}
используется вместо #{data}
, потому что jade экранирует HTML по умолчанию, который превратит все кавычки в "
placeholders.
Сначала он выглядит странно странным, но он работает. В основном вы берете объект JS на сервере, превращая его в строку, передавая эту строку в скомпилированное представление и отправляя ее в браузер. Когда документ, наконец, дойдет до браузера, он должен выглядеть так:
// someSite.com/someView
<script type="text/javascript">
var someData = { "message": "hi" };
</script>
Надеюсь, это имеет смысл. Если бы я должен был воссоздать свой оригинальный вспомогательный метод, чтобы облегчить боль этого второго сценария, тогда он будет выглядеть примерно так:
app.use(function (req, res, next) {
res.renderWithData = function (view, model, data) {
model.data = JSON.stringify(data);
res.render(view, model);
};
next();
});
Все это - это взять свой пользовательский объект данных, подкрепить его для вас, добавить его в модель для представления, а затем отобразить представление как обычно. Теперь вы можете позвонить res.renderWithData('someView', {}, { message: 'hi' });
; вам просто нужно убедиться, что где-то в вашем представлении вы захватите эту строку данных и превратите ее в оператор присваивания переменных.
html
head
title Some Page
script.
var data = !{data};
Не ложь, все это выглядит грубо, но если это избавит вас от дополнительной поездки на сервер и того, что вы после этого сделаете, как вам это нужно. Может быть, кто-то может подумать о чем-то более умном, но я просто не понимаю, как еще вы получите данные, которые уже присутствуют в полном HTML-документе, который отображается впервые.
Edit2:
Вот рабочий пример: https://c9.io/chevex/test
Для запуска проекта вам необходимо иметь (бесплатную) Cloud9-учетную запись. Войдите в систему, откройте приложение app.js и нажмите зеленую кнопку запуска вверху.