アンダースコアの外部テンプレート
-
27-10-2019 - |
質問
私が使う アンダースコアテンプレート. 。 aを取り付けることが可能です テンプレートとしての外部ファイル?
バックボーンビューで私は持っています:
textTemplate: _.template( $('#practice-text-template').html() ),
initialize: function(){
this.words = new WordList;
this.index = 0;
this.render();
},
私のHTMLでは次のとおりです。
<script id="practice-text-template" type="text/template">
<h3>something code</h3>
</script>
うまくいきます。しかし 外部テンプレートが必要です。私はやってみます:
<script id="practice-text-template" type="text/template" src="templates/tmp.js">
また
textTemplate: _.template( $('#practice-text-template').load('templates/tmp.js') ),
また
$('#practice-text-template').load('templates/tmp.js', function(data){ this.textTemplate = _.template( data ) })
しかし、それはうまくいきませんでした。
解決
編集:この答えは古く、時代遅れです。私はそれを削除しますが、それは「受け入れられた」答えです。代わりに意見を注入します。
私はもうこれを行うことを主張しません。代わりに、すべてのテンプレートを個々のHTMLファイルに分離します。これらを非同期にロードすることを提案する人もいます(require.jsまたはある種のテンプレートキャッシュ)。それは小さなプロジェクトでうまく機能しますが、多くのテンプレートを備えた大規模なプロジェクトでは、ページの読み込みに多くの小さな非同期リクエストを作成していますが、これは本当に嫌いです。 (うーん...わかりました、Require.jsを使用して回避できます。R.JSとの初期依存関係を事前にコンパイルすることで、テンプレートについては、これはまだ間違っていると感じています)
Gruntタスク(Grunt-Contrib-JST)を使用して、すべてのHTMLテンプレートを単一のTemplates.jsファイルにコンパイルし、それを含めるのが好きです。あなたはすべての世界の最善を獲得しますIMO ...テンプレートはファイルに住み、上記のテンプレートのコンパイルはビルド時に発生します(実行時ではありません)。
以下のすべてはジャンクです
私にとっては、テンプレートにJSファイルを含めることのシンプルさを好みます。したがって、変数としてテンプレートを含むview_template.jsというファイルを作成する場合があります。
app.templates.view = " \
<h3>something code</h3> \
";
次に、スクリプトファイルを通常のファイルのように含めるのと同じくらい簡単です。
template: _.template(app.templates.view)
さらに一歩進んでください、i 実際に coffeescriptを使用するので、私のコードは実際にこのように見え、行のエスケープ文字を回避します。
app.templates.view = '''
<h3>something code</h3>
'''
このアプローチを使用すると、実際に必要ではない場合にrequire.jsを作成しません。
他のヒント
これが簡単な解決策です:
var rendered_html = render('mytemplate', {});
function render(tmpl_name, tmpl_data) {
if ( !render.tmpl_cache ) {
render.tmpl_cache = {};
}
if ( ! render.tmpl_cache[tmpl_name] ) {
var tmpl_dir = '/static/templates';
var tmpl_url = tmpl_dir + '/' + tmpl_name + '.html';
var tmpl_string;
$.ajax({
url: tmpl_url,
method: 'GET',
dataType: 'html', //** Must add
async: false,
success: function(data) {
tmpl_string = data;
}
});
render.tmpl_cache[tmpl_name] = _.template(tmpl_string);
}
return render.tmpl_cache[tmpl_name](tmpl_data);
}
「async:false」を使用すると、テンプレートが読み込まれるまで待つ必要があるため、ここでは悪い方法ではありません。
したがって、「レンダリング」関数
- 個別のHTMLファイルに各テンプレートを静的dirに保存できます
- 非常に軽量です
- コンパイルとキャッシュテンプレート
- テンプレートの読み込みロジックを要約します。たとえば、将来的には、プリロードおよびプリコンパイルされたテンプレートを使用できます。
- 使いやすいです
これが重要だと思うので、コメントを残す代わりに答えを編集しています。
テンプレートが表示されていない場合 ネイティブアプリ, 、そしてあなたは見る HIERARCHY_REQUEST_ERROR: DOM Exception 3
, 、デイブ・ロビンソンの答えを見てください 「hierarchy_request_err:dom例外3」-errorを正確に引き起こす可能性がありますか?.
基本的に、追加する必要があります
dataType: 'html'
$ .AJAXリクエストに。
このMixinを使用すると、外部テンプレートを使用してレンダリングできます アンダースコア 非常に簡単な方法で: _.templateFromUrl(url, [data], [settings])
. 。メソッドAPIはほとんど同じです アンダースコア _。テンプレート(). 。キャッシングが含まれています。
_.mixin({templateFromUrl: function (url, data, settings) {
var templateHtml = "";
this.cache = this.cache || {};
if (this.cache[url]) {
templateHtml = this.cache[url];
} else {
$.ajax({
url: url,
method: "GET",
async: false,
success: function(data) {
templateHtml = data;
}
});
this.cache[url] = templateHtml;
}
return _.template(templateHtml, data, settings);
}});
使用法:
var someHtml = _.templateFromUrl("http://example.com/template.html", {"var": "value"});
この簡単なタスクにはrequire.jsを使用したくなかったので、修正されたKoorchikのソリューションを使用しました。
function require_template(templateName, cb) {
var template = $('#template_' + templateName);
if (template.length === 0) {
var tmpl_dir = './templates';
var tmpl_url = tmpl_dir + '/' + templateName + '.tmpl';
var tmpl_string = '';
$.ajax({
url: tmpl_url,
method: 'GET',
contentType: 'text',
complete: function (data, text) {
tmpl_string = data.responseText;
$('head').append('<script id="template_' + templateName + '" type="text/template">' + tmpl_string + '<\/script>');
if (typeof cb === 'function')
cb('tmpl_added');
}
});
} else {
callback('tmpl_already_exists');
}
}
require_template('a', function(resp) {
if (resp == 'tmpl_added' || 'tmpl_already_exists') {
// init your template 'a' rendering
}
});
require_template('b', function(resp) {
if (resp == 'tmpl_added' || 'tmpl_already_exists') {
// init your template 'b' rendering
}
});
JavaScriptオブジェクトに保存するのではなく、テンプレートを文書に追加するのはなぜですか?生産バージョンでは、すべてのテンプレートが既に含まれているHTMLファイルを生成したいので、追加のAJAXリクエストを作成する必要はありません。同時に、使用しているときにコードをリファクタリングする必要はありません
this.template = _.template($('#template_name').html());
私のバックボーンビューで。
これはわずかにトピックから外れているかもしれませんが、grunt(http://gruntjs.com/)を使用できます。コマンドライン。このツールには、テンプレートコンパイラなど、たくさんのプラグインがあります。 https://npmjs.org/package/grunt-contrib-jst. 。 Githubのドキュメントを参照してください、 https://github.com/gruntjs/grunt-contrib-jst. 。 (ノードパッケージマネージャーを実行する方法も理解する必要があります。 https://npmjs.org/. 。心配しないでください、それは信じられないほど簡単で多用途です。 ))
その後、すべてのテンプレートを個別のHTMLファイルに保持し、アンダースコアを使用してすべてを事前コンパイルするツールを実行できます(これはJSTプラグインの依存関係だと思いますが、ノードパッケージマネージャーは依存関係を自動インストールします)。
これはすべてのテンプレートを1つのスクリプトにコンパイルし、たとえば
templates.js
スクリプトのロードは、デフォルトでグローバル - 「JST」を設定します。これは関数の配列であり、次のようにアクセスできます。
JST['templates/listView.html']()
これに似ています
_.template( $('#selector-to-your-script-template'))
そのスクリプトタグのコンテンツを(テンプレート/)listView.htmlに入れた場合
ただし、実際のキッカーは次のとおりです。Gruntには「Watch」と呼ばれるこのタスクが付属しています。これは、基本的にローカルGrunt.jsファイルで定義したファイルの変更を監視します(これは基本的にGruntプロジェクトの構成ファイルです。 )。あなたがグラントを持っている場合、あなたのためにあなたのためにこのタスクを開始します:タイピング:
grunt watch
コマンドラインから、gruntはファイルに行ったすべての変更を監視し、変更を検出した場合、そのgrunt.jsファイルで設定したすべてのタスクを自動実行します - jst 上記のタスク。編集して、ファイルを保存し、すべてのテンプレートが多くのディレクトリやサブディレクトリに広がっている場合でも、1つのJSファイルに再コンパイルします。
JavaScriptを覆ったり、テストを実行したり、コンカテネーティングをしたり、スクリプトファイルを模倣 / Uglifingするために、同様のタスクを構成できます。そして、すべてを時計タスクに結び付けることができるため、ファイルの変更により、プロジェクトの新しい「ビルド」が自動的にトリガーされます。
grunt.jsファイルを構成する方法をセットアップして理解するには時間がかかりますが、それはよく、投資する価値があります。
JavaScriptのテンプレートに興味があり、今ではBackboneで最初のステップを踏んでいます。これは私が思いついたものであり、かなりうまく機能しているようです。
window.App = {
get : function(url) {
var data = "<h1> failed to load url : " + url + "</h1>";
$.ajax({
async: false,
url: url,
success: function(response) {
data = response;
}
});
return data;
}
}
App.ChromeView = Backbone.View.extend({
template: _.template( App.get("tpl/chrome.html") ),
render: function () {
$(this.el).html(this.template());
return this;
},
});
App.chromeView = new App.ChromeView({ el : document.body });
App.chromeView.render();
データ型を「テキスト」に設定して、それを機能させる必要がありました。
get : function(url) {
var data = "<h1> failed to load url : " + url + "</h1>";
$.ajax({
async: false,
dataType: "text",
url: url,
success: function(response) {
data = response;
}
});
return data;
}
jqueryを使用することに役立つソリューションを見つけました。
jquery.load()メソッドを使用して、メインのHTMLファイルにUnderscoreテンプレートコードを追加します。
そこにあると、テンプレートを生成するためにそれを使用しています。すべてが同期して起こる必要があります!
コンセプトは次のとおりです。
アンダースコアマップテンプレートコードがあります:
<!-- MAP TEMPLATE-->
<script type="text/template" id="game-map-template">
<% _.each(rc, function(rowItem, index){ %>
<ul class="map-row" data-row="<%- index %>">
<li class="map-col <%- colItem.areaType ? 'active-area' : '' %>"></li>
...
</script>
そして、そのコードを呼び出したファイルに入れました map-template.html
その後、テンプレートファイルのAAラッパーを作成します。
<div id="templatesPool"></div>
次に、そのファイルをメインのHTMLファイルに含めます。
頭:
<!-- Template Loader -->
<script>
$(function(){
$("#templatesPool").append($('<div>').load("map-template.html"));
});
</script>
乾杯。
この質問は本当に古いことは知っていますが、Underscore AjaxテンプレートのGoogle検索で最初の結果として現れました。
私はこれのための良い解決策を見つけられないことにうんざりしていたので、私は自分のものを作成しました:
https://github.com/ziad-saab/underscore-async-templates
AJAXを使用してアンダースコアテンプレートをロードすることに加えて、<%include%>機能を追加します。誰かに役立つことを願っています。
私はjQueryを同期的に機能させることを強制していたので、約束を使用して以前の同期例を変更しました。それはほぼ同じですが、非同期に実行されます。この例では、HBSテンプレートを使用しています。
var asyncRenderHbs= function(template_name, template_data) {
if (!asyncRenderHbs.template_cache) {
asyncRenderHbs.template_cache= {};
}
var promise= undefined;
if (!asyncRenderHbs.template_cache[template_name]) {
promise= new Promise(function(resolve, reject) {
var template_url= '/templates/' + template_name;
$.ajax({
url: template_url,
method: 'GET',
success: function(data) {
asyncRenderHbs.template_cache[template_name]= Handlebars.compile(data);
resolve(asyncRenderHbs.template_cache[template_name](template_data));
},
error: function(err, message) {
reject(err);
}
});
});
} else {
promise= Promise.resolve(asyncRenderHbs.template_cache[template_name](template_data));
}
return promise;
};
次に、レンダリングされたHTMLを使用します。
asyncRenderHbs('some_template.hbs', context)
.then(function(html) {
applicationMain.append(html);
// Do other stuff here after html is rendered...
})
.catch(function(err) {
// Handle errors
});
注:他の人が議論したように、すべてのテンプレートを単一のテンプレートにコンパイルすることが望ましいでしょう。JSファイルには、多くの小さな同期AJAXが呼び出してWebページがロードされたときにテンプレートを取得するのではなく、最初にロードすることが望ましいでしょう。
フォワード警告 - ここにドラゴンになります:
ASP.NETスタック(および同様のフレームワーク)をJS-LIBSのエコシステムと調和させて作るのに苦労している人々を支援するために、以下に示すアプローチについて言及します。言うまでもなく、これは一般的な解決策ではありません。そうは言っても ...
/endforwardwarning
ASP.NETを使用している場合は、テンプレートを1つ以上の部分的なビューを自分のビューを1つ以上配置するだけで外部化できます。 .cshtml内の別名:
@Html.Partial("path/to/template")
Template.cshtml内:
// this is razorview and thusly if you ever need to use the @ character in here
// you will have to either escape it as @@ or use the html codepoint which is @
// http://stackoverflow.com/questions/3626250/escape-character-in-razor-view-engine
<script type="text/x-template" id="someId">
<span class="foo"><%= name %></span>
</script>
そして今、あなたは通常のようなテンプレートを使用できます:
_.template($("#someId").html())({ name: "Foobar" });
このとらえど的に明確なアプローチが、誰かが1時間分の頭を打つことを節約するのに役立つことを願っています。