Ich versuche, einen Adapter für ein Client-seitiges HTML/JS-Templating-System zu schreiben, um dust.js unter der Haube zu verwenden. Leider erwartet die API, dass Rendervorgänge synchron ablaufen: Die gerenderte Ausgabe sollte vom Aufruf render() zurückgegeben werden. Dust.js ist asynchron und übergibt die Renderausgabe an eine Rückruffunktion. Gibt es eine Möglichkeit, dies zu umgehen, entweder in den Dust-APIs oder durch einen verrückten Javascript-Hack?Ist es möglich, dust.js Templates synchron zu rendern?
Antwort
DustJS wird Objekte nur dann asynchron ausführen, wenn die Ressourcen, die es rendern muss (Vorlagen, Partials), noch nicht alle geladen wurden.
Wenn alle Abhängigkeiten einer Vorlage geladen sind, bevor Sie diese Vorlage ausführen, wird sie synchron ausgeführt (soweit ich das beurteilen kann). So können Sie so etwas wie tun:
var result;
dust.render("tpl", data, function(err, res) {
result = res;
});
console.log(result); // result will actually already be filled out if dustjs didn't
// have to go look for resources somewhere.
Hier ist ein vollständigeres Beispiel unten: (und hier ist ein jsfiddle Link, so können Sie ihn ausführen: http://jsfiddle.net/uzTrv/1/)
<script type="text/javascript" src="dust.js"></script>
<script>
var tpl = dust.compile("Omg {#people} {.} {/people} are here! {>partial/}", "tpl");
var partial = dust.compile("I'm a partial but I've already been included so things still run {how}", "partial");
dust.loadSource(tpl);
dust.loadSource(partial);
var data = {
people: ["jim", "jane", "jack", "julie"],
how: "synchronously!"
};
var result;
dust.render("tpl", data, function(err, res) {
result = res;
});
console.log(result);
</script>
Es könnte Fälle geben (neben der, den ich erwähnt habe) wo ich falsch liege ... ich weiß nicht alles über dustjs.
Geprüft. Das funktioniert, obwohl Sie sehr vorsichtig sein müssen, um nichts zu tun, was dazu führt, dass die Vorlage asynchron wird. – heneryville
Eine Warnung: Das dust.onload (das zum verzögerten Laden von Vorlagen/Teiltabellen verwendet werden kann) ist nicht die einzige Sache, die asynchron sein kann. Alle benutzerdefinierten Helfer oder Funktionen in Ihren JSON-Daten können auch asynchron sein, indem Sie chunk.map aufrufen und dann einen Ajax-Aufruf, setTimeout usw. durchführen. Dies ist also definitiv keine vollständige Proof-Lösung. –
Ich wollte auch eine Funktion haben, die einen Kontext akzeptiert und den Staub gerendert Text zurückgegeben. Hier ist die Lösung, die ich kam mit:
// This function sets up dust template, and returns a new function "dusterFn()"
// dusterFn() can be passed a Context, and will return the rendered text.
// @param {String} text: The template text.
// @param {String} [name]: The name of the template to register with dust. If none is provided, a random number is used.
// @param {Function} [onError]: A function that is called if an error occurs during rendering.
function getDusterFn(text, name, onError) {
var dusterFn = null;
name = name || Math.floor(Math.random() * 99999).toString();
onError = onError || function (error) { };
try {
var compiled = dust.compile(text, name)
dust.loadSource(compiled);
dusterFn = function (context) {
var dustOutput = '';
dust.render(name, context, function (error, out) {
if (error) onError(error);
dustOutput = out;
});
return dustOutput;
};
} catch (e) {
// invalid template syntax
e += "\n\nPlease check your template syntax.";
throw (e);
}
return dusterFn;
}
Nutzungs
var greetingTemplate = getDusterFn('Hello {name}, You are {age} years old!');
greetingTemplate({name: 'Jane', age: 24});
Matts Lösung gab mir einige Hinweise, wie man ein kleines Wrapper zu schreiben, die die „Hässlichkeit“ seiner Lösung verbirgt sich (durch "Hässlichkeit" Ich meine Variable außerhalb des Callbacks deklarieren, Wert innerhalb Callback zuweisen und externen Callback zurückgeben).
Es bringt nicht nur den Hack in eine kleine Funktion, sondern bindet auch den Namen des Templates. Ich finde das unglaublich hilfreich, da ich dieselbe Renderfunktion immer und immer wieder benutze, aber ich möchte nicht jedes Mal den Namen der Vorlage angeben.
function templates(template) {
return function templatesWrapper(data) {
var result;
dust.render(template, data, function onRender(err, data) {
if (err) {
throw err;
}
result = data;
});
return result;
}
}
Dies ist, wie es zu benutzen:
var renderHello = templates('hello.html');
renderHello({ username: 'Stackoverflow' });
// => <h1>Hello, Stackoverflow</h1>
- 1. Ist es möglich, wiederverwendbare Snippets in AngularJS Templates zu verwenden?
- 2. Ist es möglich, ein Bild mit HTML zu rendern?
- 3. Ist es möglich, HTML in die Javascript-Konsole zu rendern?
- 4. Ist es möglich, zwei Modelle in einem Controller zu rendern
- 5. Ist es möglich, eine Mail als HTML zu rendern?
- 6. Dust.js und Tabellen
- 7. Vuejs synchron vor dem Rendern Daten anfordern
- 8. Ist es möglich, Inline-Vorlagen zu verwenden?
- 9. Ist es möglich, mit SFINAE/Templates zu prüfen, ob ein Operator existiert?
- 10. Ist es möglich, C++ - Code mit instanziierten Templates anzuzeigen, bevor es kompiliert wird (g ++)?
- 11. In dust.js, was ist die Streaming-Schnittstelle?
- 12. Ist es möglich, Spring's Async während des Komponententests zu deaktivieren?
- 13. Templates auf T innerhalb einer Templates auf TT: Ist das möglich/korrekt?
- 14. Dust.js Escape-Zeichen
- 15. AngularJS - Ist es möglich, ng-repeat zum Rendern von HTML-Werten zu verwenden?
- 16. three.js: Ist es möglich, THREE.Points und THREE.Mesh in derselben Szene zu rendern?
- 17. Es ist möglich, HTML in einem SQL Server Reporting Services 2008-Bericht zu rendern?
- 18. Ist es möglich, serverseitigen Code mit Express und React zu rendern?
- 19. ist es möglich, eine Webseite direkt in ein Bild in Python zu rendern?
- 20. Ist es möglich, zwei Videostreams gleichzeitig auf einem einzelnen SurfaceView zu rendern?
- 21. MxGraph: Ist es möglich, ein Diagramm in HTML ohne SVG zu rendern?
- 22. Ist es möglich, ein Element in einem Elternelement ein-/auszublenden, ohne erneut zu rendern?
- 23. Ist es möglich, den Wert von $ scope.something im Skript zu rendern?
- 24. Ist es möglich, Text nicht mit der Ghostscript-Befehlszeile zu rendern?
- 25. Ist es möglich, Haskell-Frontend mit Ghcjs, Haste, Elm usw. serverseitig zu rendern?
- 26. Unkompilierte Teiltöne in dust.js
- 27. Ist es möglich, Razor-Abschnitte optional zu machen?
- 28. Ist System.Net.Mail.SmtpClient.Send synchron?
- 29. Ist es möglich, Eclipse Code-faltende Gosse schwarz zu machen?
- 30. Ist es möglich, WebView von JavaFX in Chrome zu ändern
Gute Frage! Ich möchte das gleiche wissen, weil ich dust.js in einer CouchDB "show" -Funktion (serverseitig) verwenden möchte. –
Hilft consolidate.js? – sntran
Leider sieht es so aus, als ob die API, die von consolidate.js angeboten wird, eine Callback-Funktion auf die gleiche Weise wie dust.js verwendet, also glaube ich nicht, dass es hier helfen wird:/ –