MVC: Wie viel Code sollte in einer Ansicht sein?

8

Ich bin ein Web-Entwickler und ich war lange Zeit Coder. Aber ich habe nie eine reine MVC-Architektur verwendet. Jetzt habe ich ein eigenes Projekt gestartet und beschlossen, html-css selbst zu machen und einen Coder zu engagieren. Wir haben das beliebte PHP-MVC-Framework gewählt.

Erste Schritte sind getan, einige Seiten sind codiert. Und nachdem ich auf das Ergebnis geschaut habe, habe ich die Frage ... wie viel Code soll es in Templates geben (View)?

Hier ist zum Beispiel eine Vorlagendatei:

%Vor%

Glauben Sie, dass es in dieser Vorlage zu viel Code gibt oder es normal ist?

    
Sunny Reborn Pony 15.01.2011, 09:37
quelle

7 Antworten

16

Die erste Antwort war tatsächlich genau richtig, aber der Benutzer löschte sie (wahrscheinlich aufgrund von Gruppenzwang). Im Grunde möchten Sie keine Logik in Ihrer Vorlage . In einer idealen Welt hatten Sie ein Tag für alle Modelldaten, aber da wir uns in einer HTML-Welt befinden, gibt es das nicht, also müssen Sie entweder XSLT verwenden oder ViewHelpers verwenden.

Konzentrieren wir uns auf den ViewHelper-Ansatz.

Das ist schwer zu pflegen:

%Vor%

Und es wird nicht besser, wenn Sie das PHP durch Smarty ersetzen. Dies ist einfach zu pflegen:

%Vor%

Unter der jetzt gelöschten Frage gab es einen Kommentar, der gegen diesen "Code spricht, der für Nicht-Programmierer nicht einfach zu pflegen ist, weil er jetzt nicht weiß, wo die Itemliste definiert ist und was sie tut." Aber das ist kompletter Kauderwelsch. Denken Sie eine Sekunde darüber nach.

Auf der einen Seite behaupten sie, dass Nicht-Programmierer Probleme mit einem einfachen Funktionsaufruf haben, aber auf der anderen Seite erwarten sie, dass sie den Mischmasch von PHP-Code mit HTML gemischt verstehen. Ein Designer kümmert sich nicht um die Präsentationslogik, sondern nur um die eigentliche Präsentation. Die Ausgabe.

Ein einzelner Funktionsaufruf sagt eindeutig: "Hier ist eine Artikelliste", was viel einfacher zu verstehen ist als "hier ist ein for , das ein div wiedergibt und vielleicht etwas anderes, wenn icq gegeben ist". Ein Funktionsaufruf ist so gut wie ein Tag. Es hat Input und Output klar definiert. Wie er diese Ausgabe erreicht, ist für niemanden außer für den Entwickler irrelevant.

Ihr ViewHelper kapselt die Präsentationslogik ein. Es handelt sich um ein Snippet, das Sie in allen Ihren Ansichten wiederverwenden können. Das ist viel wartungsfreundlicher als das Kopieren und Einfügen all dieser Logik bei Bedarf immer wieder. Im obigen Beispiel gibt es zwei Argumente für den Helfer:

  • $ items ist ein Array oder ein anderer traversabler Typ, der Ihre aktuellen Artikeldaten enthält
  • 'template.htm' ist der Dateiname der Vorlage, die zum Rendern der Daten verwendet wird

Ich werde die zweite Option optional machen, weil ich annehme, dass es immer die gleiche Vorlage ist. Aber da der Kommentator sich beschwerte, dass der Nicht-Programmierer nicht wissen würde, wo er suchen sollte, hielt ich es für notwendig zu zeigen, wie einfach es ist, dem Nicht-Programmierer zu sagen, wo er hinschauen soll.

%Vor%

Es könnte effizientere Ansätze geben, um die Aufnahme der Vorlage zu lösen. Die Hauptidee sollte jedoch klar sein. Blenden Sie die Präsentationslogik von der tatsächlichen Vorlage aus. Ihre "template.htm" würde dann so aussehen:

%Vor%

Nein wenn und elnes. Keine String-Verkettungen oder geschweifte Klammern. Die Logik, um zu entscheiden, wie der Benutzer kontaktiert werden kann, ist auch in einem ViewHelper verborgen. Der ganze Nicht-Coder muss jetzt wissen, ist die Argumente zu den ViewHelpers und das ist so einfach wie zu wissen, welches Attribut in ein Tag geschrieben werden soll. Geben Sie ihnen bei Bedarf einen Spickzettel.

Zugehörige Informationen:

BEARBEITEN

Aufgrund der beiden folgenden Kommentare habe ich beschlossen, diese Antwort zu erweitern. Das obige ist keine Abstraktion um der Abstraktion willen. Es ist für Wiederverwendbarkeit und Wartbarkeit. Ich habe das bereits oben erwähnt, aber lassen Sie mich das noch einmal erklären.

Eigentlich finde ich es seltsam, die Verwendung von ViewHelpers abzulehnen, weil Sie "an zwei Stellen präsent sein müssen", aber nicht über die Trennung von Kopfzeile, Banner und Fußzeile. Das ist gleich. Sie isolieren Teile, die wiederverwendbar sind, und fügen sie in ihre eigenen Vorlagen ein. Die Trennung der Logik von der Vorlage in diesem Schritt ist nur der natürliche nächste Schritt, um noch mehr Wartbarkeit zu erreichen.

Eine Ansichtsvorlage, die Logik enthält, ist effektiv ein Skript und keine Vorlage. Jede Ansichtsvorlage, die die Logik zum Zusammensetzen enthält, ist dazu verurteilt, sich selbst zu wiederholen. Dies ist bei kleinen Websites möglicherweise kein Problem, aber wenn Sie auf einer Website mit ein paar Dutzend oder sogar Hunderten von Ansichten und Widgets arbeiten, führt das Nicht-Abstrahieren dieser Teile zur Code-Duplizierung. Setzen Sie die gesamte Logik in die Vorlage und es wird schnell zu einem Wirrwarr von c & amp; p'ed Markup gemischt mit Konditionals. Für jede Duplizierung verdoppeln Sie die Zeit, die für die Änderung benötigt wird. Fügen Sie Inline-Styles und aufdringliches Javascript hinzu und Sie befinden sich in der Maintenance Hell.¹

Wenn Sie OOP für die anderen Teile Ihrer Anwendung verwenden, warum würden Sie aus Ihrer Sicht verfahrensmäßig verfahren? Wenn Sie verstanden haben, dass Sie Javascript und CSS von Ihrem HTML trennen sollten, warum würden Sie PHP in Ihre Vorlage mischen? Es macht keinen Sinn. Das Code-Snippet des OP ist ein Skript und keine Vorlage. Als solche ist es die Domäne des Entwicklers. Und deshalb wenden Sie alle guten Praktiken an, die Sie auch auf andere Teile Ihrer Anwendung anwenden. Und das schließt das Isolieren von Logik in Funktionen und / oder Klassen ein.

Zugegeben, ein Designer, der in ein Skript schaut, weiß vielleicht nicht sofort, was vor sich geht. Aber vielleicht weiß sie das auch nicht, wenn du anfängst, native PHP-Funktionen hinzuzufügen. Was macht mb_strimwidth ? Und substr ? Was ist das ?: Konstrukt?Je mehr PHP Sie hinzufügen, desto schwieriger wird es für Nicht-Entwickler zu lesen.

Wenn Sie möchten, dass Designer an Vorlagen arbeiten, geben Sie ihnen keine Skripte. Gib ihnen Vorlagen. Und wenn Sie das tun, isolieren Sie die Logik davon und ersetzen Sie sie durch einfach zu erfassende Funktionsaufrufe. Verwenden Sie Funktionsnamen, die klar kommunizieren, was die Funktion macht. Der Entwickler muss also nur wissen, ob "Ich benutze das mit dieser Eingabe, ich werde immer diese Ausgabe bekommen. Es ist mir egal, wie diese Ausgabe wird. Ich überlasse das dem Entwickler".

Durch das Isolieren der Logik in Funktionen (oder Klassen) haben Sie außerdem den unmittelbaren Vorteil, dass Sie die Logik testen können, die verwendet wird, um bestimmte Teile auf dieser Seite isoliert darzustellen. Sie müssen nicht die gesamte Umgebung einrichten, die zum Erstellen einer Seite erforderlich ist, sondern nur die erforderliche Eingabe übergeben und ihre Ausgabe bestätigen (deshalb puffert die Funktion die Zeichenfolge, statt sie auszugeben).

¹ Wenn Sie denken, dass dies kein Problem ist, empfehle ich Ihnen dringend, eine Legacy-Anwendung zu finden, die wirklich die gesamte Logik der Ansichtsvorlage enthält. Versuchen Sie ein paar Dinge zu ändern. Sobald Sie das Vergnügen hatten, durch 2500 Zeilen Spaghetti Code mit mindestens 500 Zeichen zu essen und eine Mischung aus wiederholten PHP, HTML, CSS und JavaScript zu enthalten, werden Sie wissen, wovon ich rede.

>     
Gordon 15.01.2011 12:57
quelle
9

Ich denke nicht, was Sie in der Ansicht erreichen wollen, ist zu viel Logik, aber ich denke, es sollte etwas aufgeräumt werden.

Etwas wie:

%Vor%

Ich finde das viel einfacher zu lesen, und es macht den gleichen Job. Ich denke auch nicht, dass es für einen Nicht-Coder schwierig wäre, Änderungen vorzunehmen, was letztlich das Ziel einer Ansicht ist.

    
sevenseacat 15.01.2011 09:58
quelle
2

Wenn die Templates eine Menge Logik benötigen, könnte es nützlich sein, das ViewModel-Muster

Die Logik, die bestimmt, wann ein bestimmter Block angezeigt wird, wird im Ansichtsmodell platziert.

Beispiel
Ein Vorlagenschnipsel:

%Vor%

Ein Ansichtsmodell-Snippet:

%Vor%     
Bob Fanger 15.01.2011 11:07
quelle
1

kurze Antwort:

So wenig wie möglich ist möglich.

    
Zen 15.01.2011 11:10
quelle
1

Ansicht ist keine Vorlage.

Oder zumindest - es sollte keine Vorlage sein. Ansichten sind in der Regel Instanzen von Klassen, die für den Umgang mit Präsentationslogik zuständig sind. Sie jonglieren mehrere Vorlagen und entscheiden, welche zu verwenden und welche Daten in sie übergehen.

Aber CI hat nichts davon. Sie sind im Grunde stecken mit einer Vorlage, die vorgibt, "View", und und Instanzen von ActiveRecord, die sie sagen, Sie sind "Models". Hölle ... in der richtigen MVC ist das Modell nicht einmal eine bestimmte Klasse, sondern eine Anwendungsschicht.

Auf lange Sicht wird diese Situation die Präsentationslogik und die Geschäftslogik in den Controller zwingen und gleichzeitig schwer wartbare Vorlagen und Active Records erzeugen Klassen.

    
tereško 17.03.2012 11:45
quelle
0

Ich denke, als James, zu viel Code, aber Sie können eine Array-Variable zur Funktion get_items () hinzufügen, um das Präfix und Suffix jedes Elements zu steuern, etwa wie folgt:

%Vor%     
siner 15.01.2011 10:02
quelle
0

Ihre Ansichten sollten definitiv die meisten html-Tags enthalten, daher denke ich nicht, dass eine Funktion get_items irgendwo anders platziert werden sollte. Reinige deine Vorlagen ein wenig und arbeite mit der von Karpie vorgeschlagenen alternativen Schleifensyntax. Sie könnten auch darüber nachdenken, eine vorhandene Templating-Engine wie Twig zu verwenden, aber die Views müssen auch einige Referenzen auf Ihre Daten enthalten ... Was Sie erreichen möchten, ist, dass Nicht-Programmierer Ihre HTML-Dateien bearbeiten können, ohne zu viel Skriptlogik zu verstehen.

    
Paul 15.01.2011 10:05
quelle
Django: Verwenden von Annotate, Count und Distinct in einem Queryset ___ answer21792652 ___

Wie ein Noble sagte, ist es richtig! Wenn Sie nach Namen bestellen möchten, verwenden Sie einfach Folgendes:

%Vor%     
___ qstntxt ___

Ich habe 2 Modelle, Veranstaltungsorte und Bereiche (Bereiche bestehen aus ID- und Namensfeldern). Sie sind verwandt wie: Ein Bereich hat viele Orte und jeder Ort gehört zu einem Gebiet.

Um einen Veranstaltungsort einem Bereich zuzuweisen, gebe ich gerade die area_id-Nummer in ein Textfeld auf der Seite zum Erstellen eines neuen Veranstaltungsortes ein. Ich kann dann anzeigen, zu welchem ​​Bereich der Veranstaltungsort gehört:

%Vor%

Anstatt die ID-Nummer des Gebiets in das Formular eingeben zu müssen, hätte ich gerne eine Dropdown-Liste, die die Gebietsnamen für alle Gebietsaufzeichnungen auflistet und die ausgewählte Region mit diesem Veranstaltungsort beim Speichern verknüpft.

>

Das neue Veranstaltungsformular:

%Vor%

Ich habe es versucht:

%Vor%

Aber bekommen:

  

Sie haben ein Nullobjekt, wenn Sie es nicht getan haben   erwarte es!
Sie könnten ein erwartet haben   Instanz von Array.
Der Fehler ist aufgetreten   während der Auswertung von nil.map

Jede Hilfe wird sehr geschätzt!

    
___ tag123forms ___ Ein Formular ist im Wesentlichen ein Container, der verwendet werden kann, um eine beliebige Menge einer Teilmenge verschiedener Datentypen zu speichern. HTML-Formulare werden verwendet, um Daten an einen Server zu übergeben. VB- und C # -Formulare sind die Fenster, die für die Interaktion mit dem Benutzer verwendet werden. ___ tag123activerecord ___ Active Record ist ein Muster, das Domänenlogik mit Speicherabstraktion in einem einzelnen Objekt kombiniert. Verwenden Sie dieses Tag für Fragen zum Muster [rails-activerecord] für Fragen zum Rails ORM-Framework. ___ tag123dropdownmenu ___ Ein GUI-Element für die Benutzeroberfläche, ähnlich einem Listenfeld, in dem der Benutzer einen Wert aus einer Liste auswählen kann. Wenn eine Dropdown-Liste inaktiv ist, wird ein einzelner Wert angezeigt. Wenn es aktiviert ist, zeigt es eine Liste von Werten an, aus der der Benutzer einen auswählen kann. ___ tag123relationaldatabase ___ Eine relationale Datenbank ist eine Datenbank, die aus Beziehungsvariablen besteht (die auch * relvars *, * R-tables * oder nur * tables * genannt werden). Die Definitions-, Manipulations- und Integritätsregeln von relationalen Datenbanken basieren auf relationalen Operationen, die der Relationalen Algebra und Kalkül entsprechen oder ähnlich sind. Relationale Datenbankprinzipien sind die Grundlage für einen wesentlichen Teil der Theorie und Praxis des Datenmanagements. ___ tag123rubyonrails ___ Ruby on Rails ist ein Open-Source-Full-Stack-Webanwendungs-Framework, das in Ruby geschrieben ist. Es folgt dem populären MVC-Framework-Modell und ist bekannt für seinen "convention over configuration" -Ansatz für die Anwendungsentwicklung. ___ answer4739839 ___

Es sieht so aus als ob %code% nicht definiert ist und vielleicht auch ein paar andere Probleme. Versuchen Sie Folgendes:

%Vor%     
___