Kürzlich bin ich auf einen Schnurrbart gestoßen, der angeblich eine Vorlage ohne Logik ist .
Es gibt jedoch keine Erklärung dafür, warum es logiklos gestaltet ist. Mit anderen Worten, was ist der Vorteil einer Vorlage ohne Logik?
Kürzlich bin ich auf einen Schnurrbart gestoßen, der angeblich eine Vorlage ohne Logik ist .
Es gibt jedoch keine Erklärung dafür, warum es logiklos gestaltet ist. Mit anderen Worten, was ist der Vorteil einer Vorlage ohne Logik?
Antworten:
Mit anderen Worten, es verhindert, dass Sie sich in den Fuß schießen. In den alten JSP-Tagen war es sehr üblich, JSP-Dateien mit Java-Code zu bestreuen, was das Refactoring erheblich erschwerte, da Ihr Code verstreut war.
Wenn Sie die Logik in Vorlagen durch Design verhindern (wie dies bei Schnurrbart der Fall ist), müssen Sie die Logik an einer anderen Stelle ablegen, damit Ihre Vorlagen übersichtlich werden.
Ein weiterer Vorteil besteht darin, dass Sie gezwungen sind, über die Trennung von Bedenken nachzudenken: Ihr Controller oder Logikcode muss die Datenmassage durchführen, bevor Sie Daten an die Benutzeroberfläche senden. Wenn Sie Ihre Vorlage später gegen eine andere austauschen (nehmen wir an, Sie verwenden eine andere Vorlagen-Engine), ist der Übergang einfach, da Sie nur UI-Details implementieren mussten (da die Vorlage keine Logik enthält, denken Sie daran).
Ich habe das Gefühl, dass ich meiner Meinung nach fast alleine bin, aber ich bin fest im gegenüberliegenden Lager. Ich glaube nicht, dass die mögliche Vermischung von Geschäftslogik in Ihren Vorlagen Grund genug ist, nicht die volle Leistung Ihrer Programmiersprache zu nutzen.
Das übliche Argument für Vorlagen ohne Logik ist, dass Sie, wenn Sie vollen Zugriff auf Ihre Programmiersprache haben, möglicherweise Logik einmischen, die keinen Platz in einer Vorlage hat. Ich finde das ähnlich wie die Argumentation, dass Sie einen Löffel verwenden sollten, um Fleisch zu schneiden, weil Sie sich schneiden könnten, wenn Sie ein Messer verwenden. Dies ist sehr richtig, und dennoch werden Sie weitaus produktiver sein, wenn Sie letzteres verwenden, wenn auch vorsichtig.
Betrachten Sie beispielsweise das folgende Vorlagen-Snippet mit dem Schnurrbart :
{{name}}:
<ul>
{{#items}}
<li>{{.}}</li>
{{/items}}
</ul>
Ich kann das verstehen, aber ich finde Folgendes (mit Unterstrich ) viel einfacher und direkter:
<%- name %>:
<ul>
<% _.each(items, function(i){ %>
<li><%- i %></li>
<% }); %>
</ul>
Abgesehen davon verstehe ich, dass logiklose Vorlagen Vorteile haben (zum Beispiel können sie ohne Änderungen mit mehreren Programmiersprachen verwendet werden). Ich denke, diese anderen Vorteile sind sehr wichtig. Ich glaube einfach nicht, dass ihre logiklose Natur eine davon ist.
name
und items
könnte JavaScript enthalten.
Schnurrbart ist logiklos?
Ist das nicht:
{{#x}}
foo
{{/x}}
{{^x}}
bar
{{/x}}
Ziemlich ähnlich?
if x
"foo"
else
"bar"
end
Und ist es nicht , dass ziemlich ähnlich ist (sprich: fast eine Definition) Präsentationslogik?
if x > 0 && x < 10
) ... Obwohl es möglich ist, Moustache mit oder ohne Logik zu verwenden, liegt es an Ihnen. Immerhin ist es nur ein Werkzeug.
Eine Vorlage ohne Logik ist eine Vorlage, die Löcher enthält, die Sie füllen müssen, und nicht, wie Sie sie füllen. Die Logik wird an einer anderen Stelle platziert und direkt der Vorlage zugeordnet. Diese Trennung von Bedenken ist ideal, da die Vorlage dann leicht mit einer anderen Logik oder sogar mit einer anderen Programmiersprache erstellt werden kann.
Aus dem Schnurrbart-Handbuch :
Wir nennen es "logiklos", weil es keine if-Anweisungen, else-Klauseln oder for-Schleifen gibt. Stattdessen gibt es nur Tags. Einige Tags werden durch einen Wert ersetzt, andere durch nichts und andere durch eine Reihe von Werten. In diesem Dokument werden die verschiedenen Arten von Moustache-Tags erläutert.
Die Kehrseite der Medaille ist, dass Sie in einem verzweifelten Versuch, die Geschäftslogik aus der Präsentation herauszuhalten, am Ende viel Präsentationslogik in das Modell einfügen. Ein häufiges Beispiel könnte sein, dass Sie "ungerade" und "gerade" Klassen in abwechselnde Zeilen in einer Tabelle einfügen möchten, was mit einem einfachen Modulo-Operator in der Ansichtsvorlage möglich ist. Wenn Ihre Ansichtsvorlage dies jedoch nicht zulässt, müssen Sie in Ihren Modelldaten nicht nur speichern, welche Zeile ungerade oder gerade ist, sondern je nachdem, wie begrenzt Ihre Vorlagen-Engine ist, müssen Sie möglicherweise sogar Ihr Modell verschmutzen mit den Namen der tatsächlichen CSS-Klassen. Ansichten sollten von Modellen getrennt sein, Punkt. Modelle sollten aber auch View-unabhängig sein, und genau das lassen Sie viele dieser "No-Logic" -Vorlagen-Engines vergessen. Logik geht an beiden Orten,tut tatsächlich , um richtig zu entscheiden, wohin es geht. Handelt es sich um ein Präsentationsproblem oder um ein Geschäfts- / Datenproblem? In dem Bestreben, 100% makellose Aussichten zu haben, landet die Verschmutzung nur an einem anderen weniger sichtbaren, aber ebenso unangemessenen Ort.
Es gibt eine wachsende Bewegung zurück in die andere Richtung, und hoffentlich konzentrieren sich die Dinge irgendwo im vernünftigeren Mittelweg.
Dadurch werden Ihre Vorlagen übersichtlicher und Sie müssen die Logik an einem Ort aufbewahren, an dem sie ordnungsgemäß auf Einheiten getestet werden kann.
Dieses Gespräch fühlt sich an, als würden die Mönche des Mittelalters darüber diskutieren, wie viele Engel auf das Ende einer Stecknadel passen. Mit anderen Worten, es fängt an, sich religiös, vergeblich und falsch konzentriert zu fühlen.
Mini-Rant folgt (zögern Sie nicht zu ignorieren):
Wenn Sie nicht weiterlesen möchten. Meine kurze Antwort auf das obige Thema lautet: Ich bin mit logiklosen Vorlagen nicht einverstanden. Ich betrachte es als eine Programmierform des Extremismus. :-) :-)
Jetzt geht mein Geschwätz in vollem Gange weiter: :-)
Ich denke, wenn man viele Ideen auf die Spitze treibt, wird das Ergebnis lächerlich. Und manchmal (dh dieses Thema) ist das Problem, dass wir die "falsche" Idee auf die Spitze treiben.
Das Entfernen aller Logik aus der Ansicht ist "lächerlich" und die falsche Idee.
Treten Sie für einen Moment zurück.
Die Frage, die wir uns stellen müssen, ist, warum die Logik entfernt wird. Das Konzept ist offensichtlich die Trennung von Bedenken . Halten Sie die Ansichtsverarbeitung so weit wie möglich von der Geschäftslogik getrennt. Warum das? Es ermöglicht uns, Ansichten auszutauschen (für verschiedene Plattformen: Mobil, Browser, Desktop usw.), und es ermöglicht uns, den Kontrollfluss, die Seitenfolge, Validierungsänderungen, Modelländerungen, Sicherheitszugriff usw. einfacher auszutauschen. Auch wenn dies logisch ist Aus den Ansichten entfernt (insbesondere aus Webansichten), werden die Ansichten viel lesbarer und daher wartbarer. Ich verstehe das und stimme dem zu.
Der übergeordnete Schwerpunkt sollte jedoch auf der Trennung von Bedenken liegen. Nicht 100% logiklose Ansichten. Die Logik in den Ansichten sollte sich darauf beziehen, wie das "Modell" gerendert wird. Für mich ist die Logik in den Ansichten vollkommen in Ordnung. Sie können eine Ansichtslogik haben, die keine Geschäftslogik ist.
Ja, damals, als wir JSPs, PHP- oder ASP-Seiten mit wenig oder keiner Trennung von Codelogik und Ansichtslogik geschrieben haben, war die Wartung dieser Web-Apps ein absoluter Albtraum. Glauben Sie mir, ich weiß, ich habe einige dieser Monstrositäten geschaffen und dann beibehalten. Während dieser Wartungsphase habe ich den Fehler meiner und der meiner Kollegen (viszeral) wirklich verstanden. :-) :-)
So wurde das Edikt von oben (die Branchenexperten), Sie müssen Ihre Web-Apps mit so etwas wie einem Front-View-Controller (der an Handler oder Aktionen gesendet wird [wählen Sie Ihr Web-Framework]) strukturieren und Ihre Ansichten dürfen keinen Code enthalten . Die Ansichten sollten zu dummen Vorlagen werden.
Daher stimme ich im Allgemeinen dem obigen Gefühl zu, nicht in Bezug auf die Besonderheiten der Elemente des Edikts, sondern vielmehr in Bezug auf die Motivation hinter dem Edikt - nämlich den Wunsch nach einer Trennung der Bedenken zwischen Sichtweise und Geschäftslogik.
In einem Projekt, an dem ich beteiligt war, haben wir versucht, der Idee der logiklosen Sichtweise bis zum lächerlichen Extrem zu folgen. Wir hatten eine selbst entwickelte Vorlagen-Engine, mit der wir Modellobjekte in HTML rendern konnten. Es war ein einfaches Token-basiertes System. Es war aus einem sehr einfachen Grund schrecklich. Manchmal mussten wir uns in einer Ansicht entscheiden, ob ich diesen kleinen HTML-Ausschnitt anzeigen soll oder nicht. Die Entscheidung basiert normalerweise auf einem bestimmten Wert im Modell. Wie machen Sie das, wenn Sie absolut keine Logik in der Ansicht haben? Das kannst du nicht. Ich hatte einige wichtige Auseinandersetzungen mit unserem Architekten darüber. Die Front-End-HTML-Leute, die unsere Ansichten geschrieben haben, waren völlig behindert, als sie damit konfrontiert wurden, und waren sehr gestresst, weil sie ihre ansonsten einfachen Ziele nicht erreichen konnten. Deshalb habe ich das Konzept einer einfachen IF-Anweisung in unsere Template-Engine eingeführt. Ich kann Ihnen die Erleichterung und die daraus resultierende Ruhe nicht beschreiben. Das Problem wurde mit einem einfachen IF-Statement-Konzept in unseren Vorlagen gelöst! Plötzlich wurde unser Template-Motor gut.
Wie sind wir in diese dumme, stressige Situation gekommen? Wir haben uns auf das falsche Ziel konzentriert. Wir haben die Regel befolgt, Sie dürfen keine Logik in Ihren Ansichten haben. Das war falsch. Ich denke, die "Faustregel" sollte sein, diese Menge an Logik in Ihren Ansichten zu minimieren. Wenn Sie dies nicht tun, können Sie versehentlich zulassen, dass sich die Geschäftslogik in die Ansicht einschleicht - was gegen die Trennung von Bedenken verstößt.
Ich verstehe, wenn Sie erklären, dass "Sie keine Logik in den Ansichten haben müssen", wird es leicht zu erkennen, wann Sie ein "guter" Programmierer sind. (Wenn das dein Maß für Güte ist). Versuchen Sie nun, eine Web-App mit mittlerer Komplexität mit der oben genannten Regel zu implementieren. Es ist nicht so einfach zu machen.
Für mich ist die Regel der Logik in den Ansichten nicht so eindeutig, und ehrlich gesagt möchte ich, dass sie dort ist.
Wenn ich in den Ansichten viel Logik sehe, erkenne ich einen Codegeruch und versuche, den größten Teil der Logik aus den Ansichten zu entfernen. Ich versuche sicherzustellen, dass die Geschäftslogik anderswo lebt. Ich versuche, die Bedenken zu trennen. Aber wenn ich anfange, mit Leuten zu chatten, die sagen, wir müssen jede Logik aus der Sicht entfernen, dann ist das für mich nur ein Hauch von Fanatismus, da ich weiß, dass Sie in Situationen wie den oben beschriebenen enden können.
Ich bin mit meinem Geschwätz fertig. :-)
Prost,
David
Das beste Argument, das ich für logiklose Vorlagen gefunden habe, ist, dass Sie genau die gleichen Vorlagen sowohl auf dem Client als auch auf dem Server verwenden können. Sie brauchen jedoch nicht wirklich logisch, nur eine, die ihre eigene "Sprache" hat. Ich stimme den Leuten zu, die sich beschweren, dass Schnurrbart sinnlos einschränkend ist. Danke, aber ich bin ein großer Junge und kann meine Vorlagen ohne Ihre Hilfe sauber halten.
Eine andere Möglichkeit besteht darin, nur eine Template-Syntax zu finden, die eine Sprache verwendet, die sowohl auf dem Client als auch auf dem Server unterstützt wird, nämlich Javascript auf dem Server, entweder mithilfe von node.js, oder Sie können einen js-Interpreter und json über so etwas wie therubyracer verwenden.
Dann könnten Sie so etwas wie haml.js verwenden, das viel sauberer ist als jedes der bisher bereitgestellten Beispiele und großartig funktioniert.
In einem Satz: Logiklos bedeutet, dass die Vorlagen-Engine selbst weniger komplex ist und daher einen geringeren Platzbedarf hat und es weniger Möglichkeiten gibt, sich unerwartet zu verhalten.
Obwohl die Frage alt und beantwortet ist, möchte ich meine 2 ¢ hinzufügen (was wie ein Scherz klingt, aber es ist nicht so, es geht um Einschränkungen und wenn sie inakzeptabel werden).
Das Ziel einer Vorlage ist es, etwas zu rendern und keine Geschäftslogik auszuführen. Jetzt gibt es eine dünne Linie zwischen der Unfähigkeit, das zu tun, was Sie in einer Vorlage tun müssen, und der Verwendung von "Geschäftslogik". Obwohl ich Moustache sehr positiv gegenüberstand und versuchte, ihn zu verwenden, konnte ich in ziemlich einfachen Fällen nicht das tun, was ich brauchte.
Das "Massieren" der Daten (um die Wörter in der akzeptierten Antwort zu verwenden) kann zu einem echten Problem werden - es werden nicht einmal einfache Pfade unterstützt (etwas, das Handlebars.js adressiert). Wenn ich Ansichtsdaten habe und diese jedes Mal anpassen muss, wenn ich etwas rendern möchte, weil meine Vorlagen-Engine zu einschränkend ist, ist dies am Ende nicht hilfreich. Und es besiegt einen Teil der Plattformunabhängigkeit, die Schnurrbart für sich beansprucht; Ich muss die Massagelogik überall duplizieren.
Nach einiger Frustration und nachdem wir andere Template-Engines ausprobiert hatten, erstellten wir unsere eigene (... noch eine andere ...), die eine von den .NET Razor-Templates inspirierte Syntax verwendet. Es wird auf dem Server analysiert und kompiliert und generiert eine einfache, in sich geschlossene JS-Funktion (eigentlich als RequireJS-Modul), die aufgerufen werden kann, um die Vorlage "auszuführen", und als Ergebnis eine Zeichenfolge zurückgibt. Das von Brad gegebene Beispiel würde bei Verwendung unseres Motors so aussehen (was ich persönlich im Vergleich zu Moustache und Underscore weitaus besser lesbar finde):
@name:
<ul>
@for (items) {
<li>@.</li>
}
</ul>
Eine weitere logikfreie Einschränkung traf uns beim Aufrufen von Partials mit Moustache. Während Partials von Moustache unterstützt werden, gibt es keine Möglichkeit, die Daten anzupassen, die zuerst übergeben werden sollen. Anstatt in der Lage zu sein, eine modulare Vorlage zu erstellen und kleine Blöcke wiederzuverwenden, werde ich am Ende Vorlagen mit wiederholtem Code erstellen.
Wir haben das gelöst, indem wir eine von XPath inspirierte Abfragesprache implementiert haben, die wir JPath nannten. Grundsätzlich verwenden wir anstelle von / zum Überqueren von Kindern Punkte, und es werden nicht nur Zeichenfolgen-, Zahlen- und Boolesche Literale unterstützt, sondern auch Objekte und Arrays (genau wie JSON). Die Sprache ist nebenwirkungsfrei (ein Muss für Vorlagen), ermöglicht jedoch das "Massieren" von Daten nach Bedarf durch Erstellen neuer Literalobjekte.
Angenommen, wir möchten eine "Datenraster" -Tabelle mit anpassbaren Headern und Links zu Aktionen in den Zeilen rendern und später mithilfe von jQuery dynamisch Zeilen hinzufügen. Die Zeilen müssen daher teilweise sein, wenn ich den Code nicht duplizieren möchte. Und hier beginnt das Problem, wenn einige zusätzliche Informationen, z. B. welche Spalten gerendert werden sollen, Teil des Ansichtsmodells sind, und dies gilt auch für diese Aktionen in jeder Zeile. Hier ist ein aktueller Arbeitscode, der unsere Vorlagen- und Abfrage-Engine verwendet:
Tabellenvorlage:
<table>
<thead>
<tr>
@for (columns) {
<th>@title</th>
}
@if (actions) {
<th>Actions</th>
}
</tr>
</thead>
<tbody>
@for (rows) {
@partial Row({ row: ., actions: $.actions, columns: $.columns })
}
</tbody>
</table>
Zeilenvorlage:
<tr id="@(row.id)">
@for (var $col in columns) {
<td>@row.*[name()=$col.property]</td>
}
@if (actions) {
<td>
@for (actions) {
<button class="btn @(id)" value="@(id)">@(name)...</button>
}
</td>
}
</tr>
Aufruf aus JS-Code:
var html = table({
columns: [
{ title: "Username", property: "username" },
{ title: "E-Mail", property: "email" }
],
actions: [
{ id: "delete", name: "Delete" }
],
rows: GetAjaxRows()
})
Es enthält keine Geschäftslogik, ist jedoch wiederverwendbar und konfigurierbar und außerdem frei von Nebenwirkungen.
row
Objekt übernommen werden sollen, anstatt statische Namen zu verwenden. ZB wenn $col.property == 'Something'
dann dies den Inhalt von ergeben würde row.Something
.
Hier sind 3 Möglichkeiten zum Rendern einer Liste mit Zeichenanzahl. Alle außer dem ersten und dem kürzesten sind in logiklosen Vorlagensprachen.
CoffeeScript (mit Reactive Coffee Builder DSL) - 37 Zeichen
"#{name}"
ul items.map (i) ->
li i
Knockout - 100 Zeichen
<span data-bind="value: name"/>
<ul data-bind="foreach: items">
<li data-bind="value: i"/>
</ul>
Lenker / Schnurrbart - 66 Zeichen
{{name}}:
<ul>
{{#items}}
<li>{{.}}</li>
{{/items}}
</ul>
Unterstrich - 87 Zeichen
<%- name %>:
<ul>
<% _.each(items, function(i){ %>
<li><%- i %></li>
<% }); %>
</ul>
Das Versprechen von Vorlagen ohne Logik war vermutlich, dass Personen mit breiteren Fähigkeiten in der Lage sein würden, Vorlagen ohne Logik zu verwalten, ohne sich in den Fuß zu schießen. In den obigen Beispielen sehen Sie jedoch, dass das Ergebnis komplexer und nicht weniger komplex ist, wenn Sie dem stringbasierten Markup eine Sprache mit minimaler Logik hinzufügen. Außerdem siehst du aus, als würdest du PHP der alten Schule machen.
Natürlich habe ich keine Einwände dagegen, "Geschäftslogik" (umfangreiche Berechnung) aus Vorlagen herauszuhalten. Aber ich denke, dass der Preis bezahlt wird, wenn man ihnen eine Pseudosprache für die Anzeigelogik anstelle einer erstklassigen Sprache gibt. Nicht nur mehr zu tippen, sondern eine abscheuliche Mischung aus Kontextwechsel, die jemand lesen muss.
Zusammenfassend kann ich die Logik von Vorlagen ohne Logik nicht erkennen, daher würde ich sagen, dass ihr Vorteil für mich gleich Null ist, aber ich respektiere, dass viele in der Community dies anders sehen :)
Die Hauptvorteile der Verwendung von Vorlagen ohne Logik sind:
Ich stimme Brad zu: Der underscore
Stil ist leichter zu verstehen. Aber ich muss zugeben, dass der syntaktische Zucker möglicherweise nicht jedem gefällt. Wenn dies _.each
etwas verwirrend ist, können Sie eine herkömmliche for
Schleife verwenden.
<% for(var i = 0; i < items.length; i++) { %>
<%= items[i] %>
<% } %>
Es ist immer schön, wenn Sie auf Standardkonstrukte wie for
oder zurückgreifen können if
. Verwenden Sie einfach <% if() %>
oder <% for() %>
während Mustache
Verwendung etwas Neologismus für if-then-else
(und verwirrend , wenn Sie die Dokumentation gelesen haben):
{{#x}}
foo
{{/x}}
{{^x}}
bar
{{/x}}
Die Vorlagen-Engine ist großartig, wenn Sie verschachtelte Vorlagen einfach erstellen können ( underscore
Stil):
<script id="items-tmpl" type="text/template">
<ul>
<% for(var i = 0; i < obj.items.length; i++) { %>
<%= innerTmpl(obj.items[i]) %>
<% } %>
</ul>
</script>
<script id="item-tmpl" type="text/template">
<li>
<%= name %>
</li>
</script>
var tmplFn = function(outerTmpl, innerTmpl) {
return function(obj) {
return outerTmpl({obj: obj, innerTmpl: innerTmpl});
};
};
var tmpl = tmplFn($('#items-tmpl').html(), $('#item-tmpl').html());
var context = { items: [{name:'A',{name:'B'}}] };
tmpl(context);
Grundsätzlich übergeben Sie Ihr inneres tmpl als Eigenschaft Ihres Kontexts. Und nenne es entsprechend. Süss :)
Übrigens, wenn Sie nur an der Template-Engine interessiert sind, verwenden Sie die eigenständige Template-Implementierung. Bei Minimierung sind es nur 900 Zeichen (4 lange Zeilen):