Невозможно отобразить шаблон EJS на клиенте

Я кодирую приложение на экспресс, и я использую ejs как механизм просмотра / шаблона.

На пути /artistsя просматриваю представление, artists.ejsкоторое охватывает художники. При нажатии на обложку мне нужен вызов AJAX для извлечения соответствующих данных, поместить его в мой шаблон / представление для исполнителя artist.ejsи отобразить этот шаблон в моем HTML под обложкой.

Я видел этот связанный вопрос, но он не решил мой прецедент.

Все кажется ясным, но я не могу отображать данные с помощью шаблона. Я хотел бы скомпилировать серверную часть шаблона, отправить его в / artist, готовый к использованию, а затем заполнить его, когда это необходимо, с данными, полученными от вызова AJAX.

Что я наделал:

При вызове ejs.compile(str, opt)компилируется на стороне сервера, используя :router.get('/artists', function(req, res) { // Compile artist template fs.readFile('views/artist.ejs', "utf-8", function(err, template) { // Convert template file to string artist_template = ejs.compile(template); // Compile template res.render('artists.ejs', {template: artist_template}); // render page with compiled template });

<script>
    var template = <%= template %>
</script>

Я позаботился о преобразовании файла в String, поскольку компилятор ejs работает только со String (по сравнению с Jade .compileFile)

Тогда на $ . get ( '/ artist /' + artist_name , function ( data ) { var html = template ({ artist : data }); $ ( '# artist-page' ). html ( html ); } -side, я захватываю функцию :

fn

Затем по другому сценарию я извлекаю данные с помощью вызова AJAX:

fn

Но когда я звоню, я получаю:

Uncaught ReferenceError: // В файле controller.js var templates = {}; шаблоны . template1 = fs . readFileSync ( filePath1 , 'utf-8' ); // Прочитайте шаблон в виде строковых шаблонов . template2 = fs . readFileSync ( filePath2 , 'utf-8' ); ... res . render ( 'app.ejs' , { templates : templates }); // Отправить шаблоны в представлении // В поле зрения app.ejs < script type = "text / javascript" > var templates = <% - JSON . stringify ( templates ) %>; // Получить объект шаблонов (объект строк) </ script > < script type = "text / javascript" src = "/JS/ejs.min.js" > </ script > <! - Загрузить ejs RunTime -> // В site.js - javascript client / public file $ . get ( '/ artist ' , function ( data ) { var html = ejs . render ( templates . template1 , data ); // Render ejs клиентская сторона со сценарием EJS (template1 соответствует шаблону художников) $ ( '# artist -wrapper ' ). html ( html ); // Устанавливает HTML }); не определен

Когда я вызываю шаблон , я получаю:// In controller.js var templates = {}; templates.template1 = ejs.compile(fs.readFileSync(filePath1, 'utf-8'), {client: true}); // Get template as a function templates.template2 = ejs.compile(fs.readFileSync(filePath2, 'utf-8'), {client: true}); ... res.render('app.ejs', {templates: templates}); // Send templates in view

Uncaught ReferenceError: opts не определен.

Является ли функция fnжестко закодированной? Я прочитал документацию EJS и Jade, но в отношении моей проблемы мало информации.

Возможно, мне нужен шаблон на стороне клиента?

javascript,node.js,templates,client-side,ejs,

4

Ответов: 2


2

В конце концов я нашел обходной путь к моему вопросу, и я понял с вашим ответом, что вы можете действовать двумя разными способами:

1) Что я сделал: прочитайте и сохраните шаблон в виде строки, а затем визуализируйте его на стороне клиента с помощью сценария Runtime ejs.

<script type="text/javascript">
   var templates = <%- JSON.stringify(templates) %>; // Get templates object (object of functions) 
</script>   

Таким образом, я отправляю все свои шаблоны при загрузке первой страницы, а затем обрабатываю запрошенную страницу на стороне клиента. Интерес к тому, что я читал, заключается в том, что вы отправляете только объект JSON (ваши данные) через вызовы AJAX, а не всю страницу, что упрощает запрос. Только первый груз тяжелый со всеми вашими шаблонами.

2) Что я хотел бы сделать в соответствии с ответом @RyanZim: компилируя серверные части шаблонов в функции, отправляя их, а затем вызывайте их на стороне клиента: шаблон (данные). Если я хорошо понял, в этом случае нет необходимости в клиентской библиотеке EJS, и мои шаблоны больше не являются строками, а функциями:

templates.template1 = templates.template1.toString();

Однако я не могу понять их:

var template = new Function(templates.template1);
$.get('/artists', function(data) {
     var html = template(data);
     $('#artists-wrapper').html(html); // Sets HTML
});

не работает. они являются функциями на сервере, прежде чем отправлять их, но я не знаю, как их восстановить. У вас есть идея?

Я попробовал обходное решение, изменив их на String перед их отправкой:

client

Отправляйте их, а затем клиентскую сторону, преобразуйте их обратно в функции:

client

Но это тоже не сработает.

У вас есть идея, что мне здесь не хватает? И, наконец, согласны ли вы с тем, что компиляция их на стороне сервера перед использованием функций лучше с точки зрения вычислений, чем рендеринг каждого клиентского клиента?

Спасибо за помощь и надеюсь, что это поможет кому угодно!


0

Вам нужно использовать эту clientопцию на стороне сервера при компиляции для клиента. Из документов:

  • client Когда true, компилирует функцию, которая может быть отображена в браузере без необходимости загрузки EJS Runtime

https://github.com/mde/ejs#options

Ваш фрагмент кода на стороне сервера должен быть:

// Compile artist template
fs.readFile('views/artist.ejs', "utf-8", function(err, template) {
  artist_template = ejs.compile(template, {client: true}); // Use client option

  res.render('artists.ejs', {template: artist_template});
});
JavaScript, Node.js, шаблоны, на стороне клиента, EJS,