9 Stimmen

Beste Möglichkeit zum asynchronen Laden von Unterstrichvorlagen

Ich plane, backbone.js und underscore.js für die Erstellung von Websites zu verwenden, und ich werde viele underscore-Vorlagen haben:

<script type="text/template" id="search_template">
<p id="header">
//header content will go here
</p>
<p id="form">
    <label>Search</label>
    <input type="text" id="search_input" />
    <input type="button" id="search_button" value="Search" />
</p>
<p id="dynamic_date">
//dynamic data will be displayed here
</p>
</script>

Natürlich werden meine Vorlagen viel komplizierter sein.

Da ich viele davon haben werde, möchte ich nicht jedes Mal alle Vorlagen laden, wenn die Seite geladen wird. Ich möchte eine Lösung finden, bei der ich eine bestimmte Vorlage nur dann laden kann, wenn sie verwendet wird.

Eine andere Sache ist, dass die meisten meiner Vorlagen die gleiche Struktur haben werden, nur <p id="form"></p> y <p id="dynamic_date"></p> Der Inhalt wird sich unterscheiden.

Könnten Sie mir bitte vorschlagen, wie ich das machen soll?

Danke,

8voto

Gazler Punkte 81143

Bearbeiten: Ich habe einige Forschung und portiert meine iCanHaz Code zu underscore es verwendet auch localStorage verfügbar ist

Hier ist ein Github-Repository: https://github.com/Gazler/Underscore-Template-Loader

Der Code lautet:

  (function() {
    var templateLoader = {
      templateVersion: "0.0.1",
      templates: {},
      loadRemoteTemplate: function(templateName, filename, callback) {
        if (!this.templates[templateName]) {
          var self = this;
          jQuery.get(filename, function(data) {
            self.addTemplate(templateName, data);
            self.saveLocalTemplates();
            callback(data);
          });
        }
        else {
          callback(this.templates[templateName]);
        }
      },

      addTemplate: function(templateName, data) {
        this.templates[templateName] = data;
      },

      localStorageAvailable: function() {
       try {
          return 'localStorage' in window && window['localStorage'] !== null;
        } catch (e) {
          return false;
        }
      },

      saveLocalTemplates: function() {
        if (this.localStorageAvailable) {
          localStorage.setItem("templates", JSON.stringify(this.templates));
          localStorage.setItem("templateVersion", this.templateVersion);
        }
      },

      loadLocalTemplates: function() {
        if (this.localStorageAvailable) {
          var templateVersion = localStorage.getItem("templateVersion");
          if (templateVersion && templateVersion == this.templateVersion) {
            var templates = localStorage.getItem("templates");
            if (templates) {
              templates = JSON.parse(templates);
              for (var x in templates) {
                if (!this.templates[x]) {
                  this.addTemplate(x, templates[x]);
                }
              }
            }
          }
          else {
            localStorage.removeItem("templates");
            localStorage.removeItem("templateVersion");
          }
        }
      }

    };
    templateLoader.loadLocalTemplates();
    window.templateLoader = templateLoader;
  })();

Der Aufruf würde etwa so aussehen:

      templateLoader.loadRemoteTemplate("test_template", "templates/test_template.txt", function(data) {
        var compiled = _.template(data);
        $('#content').html(compiled({name : 'world'}));
      });

Hier ist meine ursprüngliche Antwort

Hier ist eine Methode, die ich für ICanHaz (Schnurrbart), der genau diese Funktion aus demselben Grund erfüllt.

window.ich.loadRemoteTemplate = function(name, callback) {
  if (!ich.templates[name+"_template"]) {
    jQuery.get("templates/"+name+".mustache", function(data) {
      window.ich.addTemplate(name+"_template", data);
      callback();
    });
  }
  else {
    callback();
  }
}

Ich rufe es dann so auf:

ich.loadRemoteTemplate(page+'_page', function() {
  $('#'+page+'_page').html(ich[page+'_page_template']({}, true));
});

3voto

Ich mag die Art und Weise, wie das Stackoverflow-Team Templating mit dem mvc-miniprofiler gemacht hat. Werfen Sie einen Blick auf diese Links:

Enthält.js ( Github-Link )

Enthält.tmpl ( Github-Link )

Sie verwenden den lokalen Speicher, um die Vorlagen lokal zwischenzuspeichern, wenn Ihr Browser die lokale Speicherung unterstützt. Wenn nicht, werden sie einfach jedes Mal geladen. Das ist eine ziemlich clevere Art, die Vorlagen zu handhaben. Auf diese Weise können Sie auch Ihre Vorlagen, die nicht sofort benötigt werden, in einer separaten Datei aufbewahren, ohne dass Ihr HTML-Code unübersichtlich wird.

Viel Glück!

2voto

Mike N Punkte 5775

Obwohl beide oben genannten Antworten funktionieren, fand ich den folgenden Ansatz viel einfacher.

Platzieren Sie Ihre in Skript-Tags verpackten Vorlagen wie folgt in einer Datei (z. B. "templates.html"):

<script type="text/template" id="template-1">
  <%- text %>
</script>

<script type="text/template" id="template-2">
  oh hai!
</script>

Dann das folgende Stück Javascript:

$(document).ready(function() {
  url ='http://some.domain/templates.html'
  templatesLoadedPromise = $.get(url).then(function(data) {
    $('body').append(data)
    console.log("Async loading of templates complete");
  }).fail(function() {
    console.log("ERROR: Could not load base templates");
  });
});

So können Sie Ihre Vorlagen ganz einfach anhand der zuvor festgelegten IDs auswählen. Ich habe das Versprechen

$.when(templatesLoadedPromise).then(function() {
  _.template($('#template-1').html(), {'text':'hello world'} )
});

Sie können dies dann erweitern und mehrere Dateien laden, wenn Sie möchten.

Als Randbemerkung habe ich festgestellt, dass alle Kernvorlagen, die für das anfängliche Rendern der Seite benötigt werden, besser in das HTML eingebettet sind (ich verwende Tornado-Module auf dem Server), aber dass der obige Ansatz sehr gut für alle Vorlagen funktioniert, die später benötigt werden (z. B. in meinem Fall die Vorlagen für ein Registrierungs-Widget, das ich seitenübergreifend verwenden möchte, ist perfekt dafür, da es nur bei Benutzerinteraktion geladen wird und nicht zum Kern der Seite gehört)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X