33

Вопрос по express, javascript, node.js – Node.js с Handlebars.js на сервере и клиенте

У меня есть приложение в Node.js, использующее Expressjs и Handlebars в качестве движка шаблонов.

Expressjs использует макеты, а затем отображает представления. Макет (layout.hbs) выглядит так:

<!doctype html>
<html lang="en">
    <head>
    </head>
  <body>
    {{{body}}}
  </body>
</html>

{{{body}}} заменяется на стороне сервера в файле node.js при доступе к маршруту. Например:

app.get('/', function(req, res){
   res.render('index'})
})

Заменит{{{body}}} тег с содержимым index.hbs.

Теперь на стороне клиента я использую Backbone.js и хочу использовать Handlebars для представлений, контролируемых с помощью Backbone. Проблема состоит в том, что, поскольку эти страницы уже отрисованы с помощью Handlebars, когда я пытаюсь использовать Handlebars внутри него (или Handlebars внутри Handlebars), он не работает. Там нет ошибок, он просто не заменяет теги данными.

Кто-нибудь сталкивался с этим раньше или есть идеи обойти?

Спасибо!

  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceedednpmjs.org/package/grunt-contrib-handlebars

    от
  • Error: User Rate Limit Exceeded

    от dzm
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
6 ответов
  • 29

    Простой способ сделать это - просто добавить

    \ перед{{ в файле руля. Например:

    <script type="text/x-template" id="todo-item-template">
    <div class="todo-view">
        <input type="checkbox" class="todo-checkbox" \{{checked}}>
        <span class="todo-content" tabindex="0">\{{text}}</span>
    </div>
    
    <div class="todo-edit">
        <input type="text" class="todo-input" value="\{{text}}">
    </div>
    
    <a href="#" class="todo-remove" title="Remove this task">
        <span class="todo-remove-icon"></span>
    </a>
    

    Приведенный выше код будет отображаться на клиенте с сохранением тегов {{..}}.

  • 71

    Вы должны использовать предварительно скомпилированные шаблоны клиенто

    в. Они быстрее выполняются и позволяют использовать один и тот же язык шаблонов на сервере и клиенте.

    Install handlebars globally npm install handlebars -g Precompile your templates handlebars client-template1.handlebars -f templates.js Include templates.js <script src="templates.js"></script> Execute the template var html = Handlebars.templates["client-template1"](context);

    https://stackoverflow.com/a/13884587/8360

  • 1

    У вас есть 2 варианта. Второй лучший способ пойти:

    1) Избавьтесь от усов

    <script type="text/x-handlebars" data-hbs="example">
      <p>\{{name}}</p>
    </script>
    

    2) Precompile

    Это скомпилирует шаблон на сервере, прежде чем он перейдет к клиенту. Это сделает шаблон готовым к использованию и уменьшит нагрузку на браузер.

  • 1

    Мне не понравилось решение для предварительной компиляции (потому что

    я хочу определять шаблоны в том же файле, где я буду их использовать), а также наивный\{{ escape-решение (потому что для этого нужен полный компилятор Handlebars и больше кода javascript), поэтому я пришел к гибридному решению, которое использует Handlebars & apos; помощники:

    1) Зарегистрируйте нового помощника под названием «шаблон» на конфигурации сервера

    var hbs = require('hbs');
    hbs.registerHelper("template", function(key, options){
        var source = options.fn().replace("\\{{", "{{");
        var ret =
        '<script>\n' + 
            key + ' = function(opt){\n' +
                'return Handlebars.template(' + hbs.handlebars.precompile(source) + ')(opt);\n' +
            '}\n' + 
        '</script>';
        return ret;
    });
    


    2) Используйте его в любом месте на вашей странице клиента (с\{{ экранирование для параметров на стороне клиента)

    {{#template "myTemplate"}}
        <div>
            <p>Hello \{{this.name}}!</p>
        </div>
    {{/template}}
    

    (сервер прекомпилирует его примерно так)

    <script>
        myTemplate = function(opt){
            return Handlebars.template(/* HBS PRECOMPILATED FUNCTION */)(opt);
        }
    </script>
    


    3) Просто вызовите функцию, где она вам нужна, в клиентском JavaScript

    var generatedHtml = myTemplate("world");   // = <div><p>Hello world!</p></div>
    $("#myDiv").html(generatedHtml);           // or whatever
    

  • 11

    Shameless self-promotion!

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

    узел-рули-прекомпилятор

    Я запустил его за пару часов на основе компилятора командной строки в wycats & apos; репо рулей. Это не самый лучший кодекс в мире, но он хорошо справляется со своей работой.

    EDIT: I am no longer maintaining this package. If you would like to take over, please contact me via Github. I mainly use Jade templates now, so it doesn't make sense for me to continue as the maintainer.

  • 14

    Да

    это трудная проблема - вроде как проблема цитирования в сценариях оболочки, которые становятся крысами. Гнездо цитируемых цитат.

    Мое решение состоит в том, чтобы использовать jade (a la haml) в expressjs (на стороне сервера) для вывода шаблонов на основе руля для клиента. Таким образом, сервер использует один синтаксис (jade), а клиент использует другой (handlebars). Я нахожусь на том же перекрестке, что и вы, поэтому у меня та же проблема.

    Конечно, нефрит не является существенным (хотя он уже готов для экспрессов). Вы можете выбрать любой (не относящийся к рулю) механизм шаблонов для сервера и / или вы можете использовать рули на сервере с вашими неруссовыми шаблонами на клиенте - до тех пор, пока два синтаксиса выбранных вами шаблонизаторов не будут сталкиваются. Поскольку я использую emberjs на клиенте, а он использует синтаксис handlebars (по умолчанию), я предпочитаю использовать синтаксис emberjs + handlebars на клиенте. Таким образом, expressjs + jade стал естественным вариантом для сервера.