Ответ 1
Могу ли я передать переменную JavaScript в шаблон?:
Можно получить больше данных в шаблоне и повторно отобразить его, но не так, как вы думаете, и не делаете другого запроса на сервер (если только он не получит больше данных, а не получить больше HTML).
Решение:
Этот вопрос будет трудно ответить без каких-либо подробностей, поэтому я собираюсь сделать некоторые предположения о том, почему вы хотите передать выбранное значение в шаблон EJS. Я сделаю все возможное, чтобы ответить на это с ограниченной информацией о ваших целях.
Кажется, что ваш пользователь выполняет некоторые действия на странице, такие как выбор источника очистки, и вы хотите визуализировать данные по-разному, основываясь на том, какой элемент выбран пользователем. Для этого вы можете повторно отобразить шаблон и передать данные, которые определяют, какой элемент выбран, с помощью помощника вида для применения определенного класса к выбранному элементу:
Вот модифицированный шаблон cleaning.ejs, с добавленным классом с помощью помощника вида:
cleaning.ejs:
<script>
// NOTE: even if uncommented, JavaScript inside a template will not run.
// var selected = 1;
</script>
<h1><%= title %></h1>
<ul>
<% for(var i=0; i<supplies.length; i++) { %>
<li>
<!-- apply a class to the selected element -->
<a class='<%= supplies[i].selected %>' href='supplies/<%= supplies[i].value %>'>
<%= supplies[i].value %>
</a>
</li>
<% } %>
</ul>
Представленный HTML выглядит следующим образом:
<script>
/** NOTE: Script blocks will not fire in rendered templates. They are ignored
// var selected = 1;
</script>
<h1>Cleaning Supplies</h1>
<ul>
<li>
<a class="" href="supplies/Broom">
Broom
</a>
</li>
<li>
<!-- Note the selected element -->
<a class="selected" href="supplies/mop">
mop
</a>
</li>
<li>
<a class="" href="supplies/Hammer">
Hammer
</a>
</li>
</ul>
Это представление было отображено с использованием следующего кода JavaScript:
// modified data structure so that array of supplies contains objects
// with the name of the item and whether or not it selected.
data = {
"title":"Cleaning Supplies",
"supplies":[
{
"value":"Broom",
"selected":""
},
{
"value":"mop",
"selected":"selected"
},
{
"value":"Hammer",
"selected":""
}
]
};
// pass data into template and render
var html = new EJS({url: 'cleaning.ejs'}).render(data);
// add HTML to the DOM using a <div id="container"></div> wrapper.
document.getElementById("container").innerHTML = html;
Как вы можете видеть, при поставке [i].selected применяет выбранный класс к элементу, который был помечен как выбранный в структуре данных. Я изменил значение href так, чтобы он обратился к объекту в элементе i-го массива вместо значения самого массива.
Теперь, когда выбранный элемент изменен, мы просто модифицируем переменную данных, повторно визуализируем шаблон EJS и добавляем его в DOM.
С помощью этого CSS в заголовке вашего документа HTML вы увидите что-то похожее на то, что показано ниже:
<style>
.selected { color:red; }
</style>
Почему JavaScript в шаблоне не запускается:
Метод, который вы пытаетесь использовать для управления значениями JavaScript или используете значения JavaScript внутри шаблона EJS, не будет работать. Это должно быть сделано в основном с учетом того, когда выполняется JavaScript.
Вы правы, думая, что шаблоны EJS скомпилированы на стороне клиента. Однако JavaScript в помощниках представления выполняется независимо от JavaScript в глобальном контексте. От взгляда на исходный код ejs.js кажется, что в процессе используется eval.
Кроме того, EJS возвращает отображаемый HTML как строку, а документация для EJS инструктирует нас вставлять эту визуализированную строку шаблона в DOM с помощью innerHTML:
document.getElementById("container").innerHTML = html;
Независимо от того, какую технологию просмотра вы используете, одна из основных истин некоторых браузеров, когда дело доходит до JavaScript, такова: Некоторые браузеры могут не оценивать блоки <script>
, добавленные в DOM, используя innerHTML.
Другими словами, в моем тестовом шаблоне, когда я попытался добавить тэг script для вывода выбранного значения в консоль, я увидел, что блок script был добавлен, но из-за способа innerHTML работает, он не был выполнен:
Пример шаблона Демонстрирует, что JavaScript не будет запущен при добавлении с помощью innerHTML:
<h1><%= title %></h1>
<ul>
<% for(var i=0; i<supplies.length; i++) { %>
<span id="selected"></span><script>console.info('test <%= i %> = <%= supplies[i] %>');</script>
<li>
<a href='supplies/<%= supplies[i] %>'>
<%= supplies[i] %>
</a>
</li>
<% } %>
</ul>
Выделенный HTML:
Как вы можете видеть ниже, операторы console.log присутствуют в HTML. Однако при добавлении с помощью innerHTML они не будут срабатывать.
Подход к технологиям просмотра - это ограничить их использование именно этим, создавая представление. Сохраняйте свою логику в "обычном JavaScript".
<h1>Cleaning Supplies</h1>
<ul>
<span id="selected"></span><script>console.info('test 0 = Brrom');</script>
<li>
<a href='supplies/Brrom'>
Brrom
</a>
</li>
<span id="selected"></span><script>console.info('test 1 = mop');</script>
<li>
<a href='supplies/mop'>
mop
</a>
</li>
<span id="selected"></span><script>console.info('test 2 = Hammer');</script>
<li>
<a href='supplies/Hammer'>
Hammer
</a>
</li>
</ul>
Дополнительные примеры и документацию можно найти в шаблонах EJS на веб-сайте Google Code Embedded JavaScript.