web-dev-qa-db-ja.com

ハンドルバー、外部テンプレートファイルの読み込み

私の目標は、次のようにすべてのHandlebarsテンプレートを単一のフォルダーに入れることです。

_templates/products.hbs
templates/comments.hbs
_

このスニペットは、Googleの大まかな検索を介していくつかの場所で見つけました。外部ファイルのHandlebarテンプレートにロードされるようです。これは、単一のインデックスファイルに多数のテンプレートを置くよりもはるかに理にかなっています。

_(function getTemplateAjax(path) {
    var source;
    var template;

    $.ajax({
        url: path, //ex. js/templates/mytemplate.handlebars
        cache: true,
        success: function(data) {
            source    = data;
            template  = Handlebars.compile(source);
            $('#target').html(template);
        }               
    });         
})()
_

問題は、この機能やその使用方法がわからないことです。なぜ関数全体が括弧で囲まれてから関数呼び出しが行われるのですか?例えば_(function x() { ... })()_これが何をしているのか分かりません。

そして、私が間違っていなければ、$('#target')は本来あるべきではないときにハードコーディングされているように見えます。さらに、これはdata変数をどこかに設定することになっていないので、テンプレートで参照される変数が機能しますか??正しい機能は次のように思われます:

_function getTemplateAjax(path, target, jsonData) {
  var source;
  var template;

  $.ajax({
    url: path, //ex. js/templates/mytemplate.handlebars
    cache: true,
    success: function(data) {
      source    = data;
      template  = Handlebars.compile(source);
      $(target).html(template(jsonData));
    }               
  });         
}
_

サイドノート:外部テンプレートファイルを実際にネイティブにサポートし、Handlebarsよりも整理された、より優れたテンプレートエンジンを誰かが教えてくれたら、私は永遠に感謝します。

別の問題:実際にファイルに_mytemplate.hbs_という名前を付けることはできません。Ajax呼び出しが発生すると、バイナリファイルとして認識され、バイナリとして処理されるためです。これは、.hbsのサーバーのMIMEタイプをtext/htmlまたはtext/plainに設定する問題だと思いますが、問題はこれがGruntサーバーであり、MIMEタイプを変更する方法がわかりません。

27
CaptSaltyJack

コードは [〜#〜] iife [〜#〜]Immediately Invoked Function Expression)でラップされます。これは、関数がすぐに実行されることを意味します。それが次の意味です:

(function x() {
  console.log('hello');
})();

次のこともできます。

(function() {
  console.log('hello');
}());

IIFEは、通常、他のコードとニース(競合しない)を再生するために、少しのコードの「プライベート」スコープを作成するために使用されます。


あなたが提供した2番目の関数はより理にかなっており、おそらく最初の関数は単なる例であったに違いありません。


ハンドルバーを使用すると、テンプレートをprecompileできるため、実行時にコンパイルする必要がありません。また、この方法では、テンプレートをロードするためだけに追加のHTTP要求を作成する必要がありません。

たとえば、次のプロジェクト構造がある場合 モデル、コレクション、およびビューはすべてmain.js内にあることに注意してくださいこの例とすべての.jsファイルはルートディレクトリにあります):

├── Gruntfile.js
├── handlebars-v2.0.0.js
├── index.html
├── main.js
├── package.json
└── templates
    └── todo.handlebars


私のtodo.handlebarsは次のようになります-Handlebars構文を使用したhtml:

<h3>{{title}}</h3>
<p>Created by: {{author}}</p>


テンプレートをプリコンパイルするには、コマンドラインで次の手順を実行します(最初にhandlebarsプリコンパイルスクリプトをインストールする必要があります:npm install -g handlebars)。

> handlebars templates/todo.handlebars -f todo.tpl.js

これで、私のプロジェクト構造は次のようになります。

├── Gruntfile.js
├── handlebars-v2.0.0.js
├── index.html
├── main.js
├── package.json
├── templates
│   └── todo.handlebars
└── todo.tpl.js

todo.tpl.jsファイルがルートディレクトリに追加されていることがわかります。ファイルに有効なJavaScriptコードが含まれているため、拡張子が.jsである限り、別の名前を付けることもできます。また、別のディレクトリを指定して出力することもできました。 todo.tpl.jsファイルは、Backbone Viewが使用する実際のテンプレートであることを忘れないでください。 HTMLをtodo.handlebarsで記述し、todo.tpl.jsとしてコンパイルします。


これでtodo.tpl.jsファイルができたので、Gruntを使用してすべてのJSテンプレートファイルをall_templates.jsファイルに連結するか、HTMLで各ファイルを直接参照できます。

  <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
  <script src="http://documentcloud.github.io/underscore/underscore-min.js"></script>
  <script src="http://documentcloud.github.io/backbone/backbone-min.js"></script>
  <script src="handlebars-v2.0.0.js"></script>
  <script src="todo.tpl.js"></script> <!-- My Template for a Todo item -->
  <script src="main.js"></script>


私の場合はmain.jsファイル内にあるBackbone Viewで、次のようなテンプレートを取得します。

var TodoView = Backbone.View.extend({
  tagName: 'li',  
  className: 'todo-item',
  events: {

  },

  // You can grab your template function with the name you chose when
  // you precompiled it from: `Handlebars.templates`
  template: Handlebars.templates.todo,

  initialize: function(options) {
    this.listenTo(this.model, 'change', this.render);
  },

  render: function() {
    this.$el.html(this.template( this.model.toJSON() ));
    return this;
  }
});


これで完了です!詳細はこちら:

50
istos

外部ファイルからテンプレートを読み取ることができます。スクリプトタグでhtmlを配置する必要はありません

$.get('templates/products.hbs', function (data) {
    var template=Handlebars.compile(data);
    $(target).html(template(jsonData));
}, 'html')
26
rinkesh

これを実現するための簡単なプラグインを作成しました。これに関する詳細: https://github.com/miketimmerman/load-template

1
Mike Timmerman