Ich benutze nterstreichungsvorlage . Ist es möglich, eine externe Datei als Vorlage anzuhängen ?
In der Backbone-Ansicht habe ich:
textTemplate: _.template( $('#practice-text-template').html() ),
initialize: function(){
this.words = new WordList;
this.index = 0;
this.render();
},
In meinem HTML ist:
<script id="practice-text-template" type="text/template">
<h3>something code</h3>
</script>
Es läuft gut. Aber Ich brauche eine externe Vorlage . Ich versuche:
<script id="practice-text-template" type="text/template" src="templates/tmp.js">
oder
textTemplate: _.template( $('#practice-text-template').load('templates/tmp.js') ),
oder
$('#practice-text-template').load('templates/tmp.js', function(data){ this.textTemplate = _.template( data ) })
aber es hat nicht funktioniert.
BEARBEITEN: Diese Antwort ist alt und veraltet. Ich würde sie löschen, aber es ist die "akzeptierte" Antwort. Ich werde stattdessen meine Meinung einbringen.
Ich würde dies nicht mehr befürworten. Stattdessen würde ich alle Vorlagen in einzelne HTML-Dateien aufteilen. Einige würden vorschlagen, diese asynchron zu laden (Require.js oder eine Art Vorlagen-Cache). Das funktioniert aber gut bei kleinen Projekten Bei großen Projekten mit vielen Vorlagen stellen Sie fest, dass Sie beim Laden von Seiten eine Menge kleiner asynchroner Anforderungen stellen, die ich nicht mag. (ugh ... ok, Sie können dies mit Require.js umgehen, indem Sie Ihre anfänglichen Abhängigkeiten mit vorkompilieren r.js, aber für Vorlagen fühlt sich das für mich immer noch falsch an)
Ich benutze gerne eine Grunt-Aufgabe (grunt-contrib-jst), um alle HTML-Vorlagen in eine einzige templates.js-Datei zu kompilieren und diese einzuschließen. Sie erhalten das Beste aus allen Welten, IMO ... Vorlagen leben in einer Datei, Kompilierung der genannten Vorlagen erfolgt zum Zeitpunkt der Erstellung (nicht zur Laufzeit), und Sie haben keine hundert winzigen asynchronen Anforderungen, wenn die Seite gestartet wird.
Alles unten ist Müll
Ich bevorzuge die Einfachheit, eine JS-Datei in meine Vorlage aufzunehmen. Ich könnte also eine Datei namens view_template.js erstellen, die die Vorlage als Variable enthält:
app.templates.view = " \
<h3>something code</h3> \
";
Dann ist es ganz einfach, die Skriptdatei wie eine normale einzuschließen und sie dann in Ihrer Ansicht zu verwenden:
template: _.template(app.templates.view)
Wenn ich noch einen Schritt weiter gehe, verwende ich tatsächlich Kaffeeskript, sodass mein Code eher so aussieht und die Escape-Zeichen am Zeilenende vermieden werden:
app.templates.view = '''
<h3>something code</h3>
'''
Mit diesem Ansatz vermeiden Sie das Einspielen von require.js, wenn dies wirklich nicht erforderlich ist.
Hier ist eine einfache Lösung:
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);
}
Die Verwendung von "async: false" ist hier kein schlechter Weg, da Sie auf jeden Fall warten müssen, bis die Vorlage geladen wird.
Also "rendern" Funktion
[Ich bearbeite die Antwort, anstatt einen Kommentar zu hinterlassen, weil ich dies für wichtig halte.]
wenn Vorlagen in native App nicht angezeigt werden und Sie HIERARCHY_REQUEST_ERROR: DOM Exception 3
, siehe Antwort von Dave Robinson auf Was genau kann einen "HIERARCHY_REQUEST_ERR: DOM Exception 3" -Fehler verursachen? .
Grundsätzlich müssen Sie hinzufügen
dataType: 'html'
auf die $ .ajax-Anfrage.
Mit diesem Mixin können Sie externe Vorlagen mithilfe von Unterstrich auf sehr einfache Weise rendern: _.templateFromUrl(url, [data], [settings])
. Die Methoden-API entspricht fast der Unterstreichung _. Template () . Caching inklusive.
_.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);
}});
Verwendung:
var someHtml = _.templateFromUrl("http://example.com/template.html", {"var": "value"});
Ich wollte require.js nicht für diese einfache Aufgabe verwenden, also habe ich die modifizierte koorchik-Lösung verwendet.
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
}
});
Warum Vorlagen an ein Dokument anhängen, anstatt sie in einem Javascript-Objekt zu speichern? Da ich in der Produktionsversion eine HTML-Datei mit allen bereits enthaltenen Vorlagen generieren möchte, muss ich keine zusätzlichen Ajax-Anforderungen stellen. Und in der gleichen Zeit muss ich in meinem Code kein Refactoring vornehmen, wie ich es benutze
this.template = _.template($('#template_name').html());
in meinen Backbone-Ansichten.
Dies ist möglicherweise ein wenig ungewöhnlich, aber Sie können Grunt (http://gruntjs.com/) verwenden, das auf node.js (http://nodejs.org/, verfügbar für alle wichtigen Plattformen) ausgeführt wird, um Aufgaben von der auszuführen Befehlszeile. Es gibt eine Reihe von Plugins für dieses Tool, wie zum Beispiel einen Template-Compiler https://npmjs.org/package/grunt-contrib-jst . Siehe Dokumentation zu GitHub, https://github.com/gruntjs/grunt-contrib-jst . (Sie müssen auch verstehen, wie der Node Package Manager ausgeführt wird, https://npmjs.org/ . Keine Sorge, es ist unglaublich einfach und vielseitig.)
Sie können dann alle Ihre Vorlagen in separaten HTML-Dateien speichern und das Tool ausführen, um sie alle mit einem Unterstrich vorzukompilieren (was meiner Meinung nach eine Abhängigkeit für das JST-Plugin darstellt, aber keine Sorge, der Node Package Manager installiert Abhängigkeiten automatisch für Sie).
So werden beispielsweise alle Ihre Vorlagen zu einem Skript zusammengefasst
templates.js
Durch das Laden des Skripts wird ein globales "JST" festgelegt, das eine Reihe von Funktionen darstellt und wie folgt aufgerufen werden kann:
JST['templates/listView.html']()
das wäre ähnlich wie
_.template( $('#selector-to-your-script-template'))
wenn Sie den Inhalt dieses Skript-Tags in (templates /) listView.html einfügen
Der eigentliche Kicker ist jedoch: Grunt wird mit der Aufgabe 'watch' ausgeliefert, die im Grunde genommen Änderungen an Dateien überwacht, die Sie in Ihrer lokalen Datei grunt.js definiert haben (im Grunde genommen eine Konfigurationsdatei für Ihr Grunt-Projekt in Javascript) ). Wenn Sie grunzen haben, starten Sie diese Aufgabe für Sie, indem Sie Folgendes eingeben:
grunt watch
über die Befehlszeile überwacht Grunt alle Änderungen, die Sie an den Dateien vornehmen, und führt automatisch alle Aufgaben aus, die Sie in der Datei grunt.js dafür eingerichtet haben, wenn Änderungen festgestellt werden - wie z. B. die jst Aufgabe oben beschrieben. Bearbeiten und speichern Sie Ihre Dateien, und alle Ihre Vorlagen werden in eine einzige js-Datei kompiliert, auch wenn sie auf mehrere Verzeichnisse und Unterverzeichnisse verteilt sind.
Ähnliche Aufgaben können konfiguriert werden, um Ihr Javascript zu löschen, Tests auszuführen, Ihre Skriptdateien zu verketten und zu verkleinern/verkleinern. Und alles kann mit der Überwachungsaufgabe verknüpft werden, sodass Änderungen an Ihren Dateien automatisch einen neuen Build Ihres Projekts auslösen.
Es braucht einige Zeit, um die Dinge einzurichten und zu verstehen, wie die grunt.js-Datei konfiguriert wird, aber es ist die investierte Zeit wert, und ich glaube, Sie werden nie wieder zu einer Arbeitsweise vor dem Grunzen zurückkehren
Ich denke dies ist das, was dir helfen könnte. Alles in der Lösung dreht sich um require.js
Bibliothek, die eine JavaScript-Datei und ein Modullader ist.
Das Tutorial unter dem obigen Link zeigt sehr gut, wie ein Backbone-Projekt organisiert werden kann. Ein Beispielimplementierung wird ebenfalls bereitgestellt. Hoffe das hilft.
Ich musste den Datentyp auf "Text" setzen, damit es für mich funktioniert:
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;
}
Ich habe mich für JavaScript-Vorlagen interessiert und mache jetzt die ersten Schritte mit Backbone. Das habe ich mir ausgedacht und es scheint ziemlich gut zu funktionieren.
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();
Ich habe eine Lösung gefunden, die für mich mit jQuery funktioniert.
Ich füge den Unterstrich-Vorlagencode mit der Methode jQuery.load () zur HTML-Hauptdatei hinzu.
Sobald es dort ist, benutze ich es zum Generieren der Vorlagen. Alles muss synchron geschehen!
Das Konzept lautet:
Ich habe einen Kartenvorlagencode mit Unterstrich:
<!-- 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>
Und ich habe diesen Code in eine Datei namens map-template.html geschrieben
Danach erstelle ich einen Wrapper für die Vorlagendateien.
<div id="templatesPool"></div>
Dann füge ich diese Datei wie folgt in meine HTML-Hauptdatei ein.
Im Kopf:
<!-- Template Loader -->
<script>
$(function(){
$("#templatesPool").append($('<div>').load("map-template.html"));
});
</script>
Prost.
Ich weiß, dass diese Frage wirklich alt ist, aber sie tauchte als erstes Ergebnis einer Google-Suche nach Ajax-Vorlagen mit Unterstreichungszeichen auf.
Ich war es leid, keine gute Lösung dafür zu finden, also habe ich meine eigene erstellt:
https://github.com/ziad-saab/underscore-async-templates
Zusätzlich zum Laden von Unterstrich-Vorlagen mit AJAX wird die Funktionalität <% include%> hinzugefügt. Ich hoffe, es kann jemandem nützlich sein.
Vorwarnung - Hier seid Drachen:
Ich erwähne den unten gezeigten Ansatz, um denjenigen zu helfen, die Schwierigkeiten haben, ASP.NET-Stacks (und ähnliche Frameworks) in Einklang mit dem Ökosystem von js-libs zu bringen. Es versteht sich von selbst, dass dies keine generische Lösung ist. Davon abgesehen ...
/ endforwardwarning
Wenn Sie ASP.NET verwenden, können Sie Ihre Vorlagen einfach auslagern, indem Sie sie in eine oder mehrere eigene Teilansichten einfügen. Aka in deinem .cshtml:
@Html.Partial("path/to/template")
In Ihrer 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>
Und jetzt können Sie die Vorlage wie gewohnt verwenden:
_.template($("#someId").html())({ name: "Foobar" });
Hoffe, dass dieser schwer fassbare Ansatz jemandem hilft, eine Stunde Kopfkratzen zu sparen.
Es war mir ein bisschen unangenehm, jQuery dazu zu zwingen, synchron zu funktionieren, deshalb habe ich das vorherige synchrone Beispiel mit Versprechungen modifiziert. Es ist so ziemlich dasselbe, läuft aber asynchron. In diesem Beispiel verwende ich hbs-Vorlagen:
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;
};
Dann verwenden Sie das gerenderte 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
});
ANMERKUNG: Wie von anderen beschrieben, ist es vorzuziehen, alle Vorlagen in eine einzige templates.js-Datei zu kompilieren und diese am Anfang zu laden, anstatt viele kleine synchrone AJAX Aufrufe zum Abrufen von Vorlagen zu haben, wenn das Die Webseite wird geladen.