34

テンプレートエンジンとしてExpressjsとHandlebarsを使用するNode.jsのアプリがあります。

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を使用しており、Backboneを介して制御されるビューにハンドルバーを使用したいと考えています。問題は、これらのページはすでにハンドルバーを介してレンダリングされているため、その中でハンドルバー(またはハンドルバー内のハンドルバー)を使用しようとすると機能しないことです。エラーはありません。タグをデータに置き換えないだけです。

誰かが以前にこれに遭遇したことがありますか、または回避策について何か考えがありますか?

ありがとうございました!

4

7 に答える 7

75

コンパイル済みのクライアントテンプレートを使用する必要があります。これらは実行速度が速く、サーバーとクライアントで同じテンプレート言語を使用できます。

  1. ハンドルバーをグローバルにインストールするnpm install handlebars -g
  2. テンプレートをプリコンパイルしますhandlebars client-template1.handlebars -f templates.js
  3. templates.jsを含める<script src="templates.js"></script>
  4. テンプレートを実行するvar html = Handlebars.templates["client-template1"](context);

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

于 2012-12-14T18:56:54.703 に答える
33

これを行う簡単な方法は、ハンドルバーファイルの\前にを追加することです。{{例えば:

<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>

上記のコードは、{{..}}タグが保持された状態でクライアントにレンダリングされます。

于 2013-09-03T22:57:21.600 に答える
14

うん、それは厄介な問題です---引用符で囲まれたネズミの巣になるシェルスクリプトの引用符の問題のようなものです。

私の解決策は、expressjs(サーバー側)でjade(a la haml)を使用して、クライアント用のハンドルバーベースのテンプレートを出力することです。このように、サーバーは1つの構文(jade)を使用し、クライアントは別の構文(handlebars)を使用します。私はあなたと同じ岐路に立っているので、同じ挑戦をしています。

もちろん、翡翠は必須ではありません(ただし、expressjs用に既製です)。サーバーに任意の(非ハンドルバー)テンプレートエンジンを選択できます。また、選択したテンプレートエンジンの2つの構文がそうでない限り、サーバーで非ハンドルバーをクライアントでテンプレート化するハンドルバーを使用できます。衝突します。クライアントでemberjsを使用していて、ハンドルバー構文(デフォルト)を使用しているため、クライアントでemberjs+ハンドルバー構文を使用することをお勧めします。そのため、expressjs+jadeがサーバーに自然に適合しました。

于 2012-04-06T08:19:23.270 に答える
11

恥知らずな自己宣伝!

私はこれと同じクライアント/サーバー共有をしたかったので、支援するために小さなnpmパッケージを作成しました。

ノード-ハンドルバー-プリコンパイラ

wycatsのハンドルバーリポジトリにあるコマンドラインコンパイラに基づいて、数時間で作成しました。これは世界で最も優れたコードではありませんが、私にとっては非常にうまく機能しています。

編集:私はもうこのパッケージを維持していません。引き継ぎをご希望の場合は、Github経由でご連絡ください。現在は主にJadeテンプレートを使用しているので、メンテナとして継続しても意味がありません。

于 2012-04-23T20:52:21.393 に答える
4

クライアント側のテンプレートをサーバー側のテンプレートに渡すことで、これを回避しました。

したがって、サーバー側では、すべてのクライアント側テンプレートを配列に読み取り、サーバー側のレンダリング関数に渡します。

ルートハンドラーで次のようにします。

readTemplates(function(err, clientTemplates) {
  res.render("page", {
    clientTemplates: clientTemplates;   
  });
});

そして、layout.hbsで:

{{#each clientTemplates}}
<script type="text/handlebars id="{{this.filename}}" >
{{{this.template}}}
</script>
{{/each}}

ここでは、拡張子のないファイル名をテンプレートIDとして使用しているため、バックボーンビューから参照できます。ああ、本番モードのキャッシュを実装することを忘れないでください。

ええ、これは最悪です。

このためにHandlebars/Express/Connectヘルパーを作成する必要があると思います。

于 2012-07-14T08:30:39.060 に答える
1

2つのオプションがあります。2番目は行くための最良の方法です:

1)口ひげを脱出する

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

2)プリコンパイル

これにより、テンプレートがクライアントに送信される前に、サーバー上でテンプレートがコンパイルされます。これにより、テンプレートをすぐに使用できるようになり、ブラウザの負担が軽減されます。

于 2014-08-08T21:12:28.490 に答える
1

コンパイル前のソリューション(テンプレートを使用するのと同じファイルでテンプレートを定義したいので)もナイーブな\{{エスケープソリューション(完全なハンドルバーコンパイラとより多くのJavaScriptコードが必要なため)も好きではなかったので、ハイブリッドを思いつきましたハンドルバーのヘルパーを使用するソリューション:

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)クライアント側のWebページの任意の場所で使用します(\{{クライアント側のパラメーターのエスケープを使用)

{{#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
于 2016-02-20T01:44:19.850 に答える