express response.render по нескольким шаблонам
Всем привет!
Только начала изучать Node.js, подтолкните, пожалуйста, в нужном направлении. Основная задача: создать одностраничный опросник. Вопросы решила описать через json. Для каждого вопроса указывается id, текст вопроса, варианты ответа, тип вопроса и т.д. Для каждого типа вопроса создала шаблон (pug). Отдельно для вопросов radio (единственный выбор), checkbox (множественный выбор), open (текстовый ответ, вписываемый в textarea) и т.д. Пример шаблона для вопроса-radio: include outer.pug table.inner_table each val in answ tr td label #[input(type='radio', name=`${id}`, value=`${val.r}`, id=`${id}_${val.r}`)] !{val.lab} Дальше, думала перебирать json и в зависимости от типа рендерить нужный шаблон: let jsonData = require('./study.json'); app.get("/", function(request, response){ for (let i=0; i<jsonData.length; i++){ if (jsonData[i].type == "radio"){ response.render("radio", jsonData[i]); }//и т.д. } //response.send("Главная страница"); }); Я понимаю, что это не правильно, да оно так и не работает. Подскажите, пожалуйста, каким способом можно подгрузить несколько шаблонов на одну страницу? Если я совсем в не ту сторону думаю, пожалуйста, тоже выскажитесь. Может надо совсем все по другому делать? |
Я с этим шаблонизатором не знаком, однако обычно рендерят не каждый элемент "вручную" в контроллере, а передают из контроллера набор данных в шаблонизатор и он уже рендерит страницу.
response.render не просто рендерит представление, но еще и отправляет его сразу же клиенту. Цитата:
У шаблонизатора pug есть директива "include" для подключения в текущий шаблон других шаблонов. |
Nexus, спасибо большое за ответ!
Цитата:
А Вы каким пользуетесь, если не секрет? Т.е. я правильно понимаю, что в контроллере я должна оставить только передачу считанного json в шаблон, а цикл по массиву и подгрузку других шаблонов по условию уже в шаблоне сделать? как-то так: let jsonData = require('./study.json'); app.get("/", function(request, response){ response.render("main", jsonData); //response.send("Главная страница"); }); а в шаблоне for (let i=0; i<jsonData.length; i++){ if (jsonData[i].type == "radio"){ include radio.pug }//и т.д. } ну с нормальным синтаксисом естественно, я просто пока не изучила его. |
Цитата:
Цитата:
|
Понятия не имею о внутренностях node, его шаблонах, но, если так по условию include radio.pug, то почему не проще?
for (let i=0; i<jsonData.length; i++) include jsonData[i].type + ".pug"; |
Nexus, Спасибо! Думала на счет react, но решила, что шаблонизатор попроще изучить будет. Постараюсь остаться пока на pug.
laimas, Спасибо! Наверное можно и так, буду изучать. |
Пока не выходит сделать все в шаблоне, но нашла другой вариант.
Выкладываю рабочее решение:write: const express = require("express"); const pug = require('pug'); const app = express(); app.set("view engine", "pug"); let jsonData = require('./study.json'); app.get("/", function (request, response) { var html = ''; for (let i = 0; i < jsonData.length; i++) { var layout = pug.compileFile('views/' + jsonData[i].type + '.pug'); var html = html + layout(jsonData[i]); } response.send(html); }); app.listen(3000); Шаблоны остались как были: include outer.pug table.inner_table each val in answ tr td label #[input(type='radio', name=`${id}`, value=`${val.r}`, id=`${id}_${val.r}`)] !{val.lab} Теперь проблема в том, что когда я увеличиваю количество вопросов до 1000 (примерное реальное количество), время загрузки страницы слишком долгое. Так что буду пытаться все-таки все в шаблоне сделать, может так быстрее будет. Если что-то получится, выложу сюда. |
Цитата:
Если для каждая таблица содержит только одну колонку, то не лучше ли таблицы заменить на div? Это уменьшит и кол-во элементов на странице (браузер немного выдохнет), и кол-во передаваемой информации на клиент (увеличится скорость полной загрузки страницы). На каждый отдельный вопрос вы создаете отдельную функцию-рендерер. Мне это кажется слишком затратным, я бы складывал созданный экземпляр рендерера в объект/карту и доставал при необходимости. У Pug, я думаю, есть механизмы внутреннего кеша, однако описанный подход все же должен сократить время рендерера. Так же список вопросов необязательно рендерить каждый раз заново, его можно кешировать. Главное заранее задаться вопросом инвалидации кеша, иначе потом может возникнуть вопрос типа: «изменил какой-то вопрос, а на сайте ничего не меняется. Что не так?». Ну и не стоит забывать о сжатии передаваемых данных на клиент, это также сократить кол-во передаваемых данных на клиент, что ускорит скорость полной загрузки страницы. |
Nexus,
целый вечер потратила на ковыряние шаблона, пытаясь его заставить отображать все вопросы в цикле. А сегодня с утра глянула, блин, оказалось, что я вместо объекта в response.render массив пихала:-E Всего-то нужно было так сделать response.render("main", {"jsonData": jsonData}); вместо response.render("main", jsonData); Теперь все заработало отображается все супер быстро!:dance: Цитата:
Спасибо за советы по сокращению html и сжатию файлов. Я попробовала на своем тесте в 1000 вопросов, теперь шаблон так быстро все рендерит (300-500 мс), что разницы совсем не увидела. Но перед запуском этой странички в рабочий режим, сожму все файлики. |
Цитата:
Сжатие с помощью Nginx: NGINX.Docs, ruhighload Какие-то внутренние файлы смысла сжимать нет, вы только потеряете возможность вносить в них изменения без декомпрессии. |
Часовой пояс GMT +3, время: 04:57. |