Sollte man angesichts des Konzepts von "Skinny Controllern, Fat Models" und der allgemeinen Akzeptanz, dass Views Models direkt aufrufen können, wenn Daten für die Ausgabe benötigt werden, in Betracht ziehen, die "Get and Display" -Teile von Anforderungen in den Views und nicht den Controller zu behandeln? Zum Beispiel (versucht, den Code ziemlich allgemein zu halten):
Regler
<?php
class Invoice extends Base_Controller {
/**
* Get all the invoices for this month
*/
public function current_month() {
// as there's no user input let's keep the controller very skinny,
// DON'T get data from the Model here, just load the view
$this->load->view('invoice/current_month');
}
}
Aussicht
<?php
// directly retrieve current month invoices here
$invoices = $this->invoice_model->get_current_month();
// get some other display-only data, e.g. a list of users for a separate list somewhere on the page
$users = $this->user_model->get_users();
?>
<h1>This month's invoices</h1>
<ul>
<?php foreach ($invoices as $invoice) { ?>
<li><?php echo $invoice['ref']; ?></li>
<?php } ?>
</ul>
Für mich ist dies zumindest in den Fällen sinnvoll, in denen eine Anfrage im Wesentlichen nur eine Ansicht ist. Warum sollte der Controller die Daten sammeln und an die Ansicht weitergeben müssen, wenn er sie nur selbst abrufen kann? Dadurch bleibt der Controller offen für die reine Verarbeitung auf Anwendungsebene (z. B. Bearbeitung von GET / POST-Anforderungen, Verwaltung von Zugriffsrechten und Berechtigungen usw.) sowie für die Wiederverwendbarkeit der Modelle und aller anderen guten Dinge.
Wenn dieses Beispiel erweitert wurde, damit ein Benutzer die Ergebnisse filtern kann, verarbeitet der Controller nur den POST aus dem Formular und übergibt die Filter an die Ansicht, die dann die Daten erneut anfordert, diesmal mit den Filtern.
Ist dies ein gültiger Ansatz für die Entwicklung einer MVC-Anwendung? Oder übersehe ich einen wichtigen Teil der Rolle, die ein Controller spielen sollte?
quelle
offers_model->get_latest()
erfolgen? Das Hinzufügen zu jeder Methode im Controller (wie ich es dummerweise zuvor versucht habe) scheint übertrieben und deutlich ungetrocknet zu sein.offers_model->get_latest()
zu einerProductViewModel
Basisklasse oder ähnlichem hinzufügen .Nein, das ist nicht richtig. View kann Models nicht direkt aufrufen. Ansichten sollten keinen Zugriff auf Modellobjekte haben, es sei denn, der Programmierer hat diese Objekte aus irgendeinem Grund für die Ansicht verfügbar gemacht.
Das löscht im Grunde den Controller und besiegt den Punkt, sie zu haben.
Der Controller sammelt die Daten nicht. Das Modell sammelt die Daten. Der Controller entscheidet, ob diese Daten an die Ansicht übergeben werden sollen. In der Ansicht werden nur die Daten dargestellt.
Nein.
Der Controller prüft, ob die POST-Daten gültig sind, übergibt diese Daten dann als Optionen an das Modell, das dann die Datenquelle abfragt und die Daten zurückgibt, und der Controller übergibt diese an die Ansicht.
Der Controller fungiert als Handler für Anforderungen des Browsers. Ein Dispatcher sendet die Anforderung an die Aktion eines Controllers, die die Anforderung wiederum an die Modelle verteilt. Die Modelle enthalten die gesamte Geschäftslogik (dies ist der fette Teil) und geben die Daten an den Controller zurück. Der Controller kann die Daten dann vereinfachen und anpassen, damit die Ansicht sie leichter darstellen kann.
Der Zweck der Ansicht besteht darin, die Struktur und Abhängigkeit zwischen der Darstellung von HTML und der DataSource zu entkoppeln. Dies kann zwar schwierig sein. Ansichten zeigen nicht immer Daten an, die direkt von einem Modell stammen. Der Controller fügt häufig relevante relevante Daten hinzu.
Ich bin mir sicher, dass es auf MVC viele Tutorials gibt. Ich würde empfehlen, einige davon zu lesen.
quelle
Ich fand Ihre Frage sehr interessant, da ich kürzlich beim Erlernen von Python auf dasselbe Problem gestoßen bin.
Während die gegebenen Antworten ein überzeugendes Argument darstellen, dachte ich, ich würde eine andere Meinung hinzufügen, auf die ich gestoßen bin, in der die Ansicht den Status des Modells erhält, ohne den Controller zu durchlaufen.
Ich bin nicht in der Lage zu sagen, welche der Meinungen "richtig" ist, und um ehrlich zu sein, bin ich etwas verwirrter, nachdem ich die Antworten hier und den verlinkten Artikel gelesen habe.
Vollständiger Text des Artikels hier .
quelle
Eine andere zu berücksichtigende Sache ist, dass Sie anscheinend das automatisch geladen haben
user_model
und derinvoice_model
Ansicht erlauben, auf sie zuzugreifen. Damit dies zuverlässig funktioniert, laden Sie wahrscheinlich alle Ihre Modelle automatisch (weil es$this->load->model()
in einer Ansicht einfach falsch aussieht, nicht wahr ...)Wenn Sie dies tun, wird Ihr Stapel unnötig aufgebläht, indem Sie eine Reihe von Dingen laden, die möglicherweise nie verwendet werden. Ein Grund für die Verwendung mehrerer Modelle besteht darin, dass Sie die zugehörige Logik kapseln und nur das laden können, was Sie für eine bestimmte Aufgabe benötigen.
Dies sieht aus wie CodeIgniter. Ich habe viel CI-Entwicklung betrieben und kann aus persönlicher Erfahrung mitteilen, dass Sie wirklich nicht mehr automatisch laden möchten, als Sie wirklich müssen. Versuchen Sie,
$this->output->enable_profiler(TRUE);
den Konstruktor eines Controllers hinzuzufügen, und spielen Sie mit Autoloads (einschließlich Hilfsprogrammen wiedatabase
): Sie werden wahrscheinlich eine signifikante Änderung der Lade- und Ausführungszeiten feststellen, insbesondere aber der Speicherzuweisung.quelle
load->model
in den meisten Controllern und Methoden viel Gleiches zu haben . Die Nichtverwendung einer richtigen Autoload-Funktion ist eines der Dinge, die ich an der Abwärtskompatibilität von CI am wenigsten mag, aber das ist eine ganz andere Diskussion ...Die kurze Antwort lautet, dass die Form Ihres Codebeispiels täuschend intuitiv ist. Es scheint, dass dies ein "leicht zu denkender" Weg ist.
Problem Nr. 1
Ihre
Model
undView
Objekte werden eng miteinander verbunden.Wenn Sie jemals Methoden in der hinzufügen oder entfernen müssen
Model
, müssen Sie diese möglicherweiseView
entsprechend ändern .Grundsätzlich wird MVC aus den Befehls- und Beobachtermustern abgeleitet . Sie möchten ein unabhängiges 'Modell', das über eine Schnittstelle / API bearbeitet wird , in die
Controller
sich der Benutzer einbinden kann (dh Delegierung).Häufig bedeutet dies, dass Instanzen in a injiziert
Model
und als Eigenschaften von diesen gespeichert werden . Übergeben Sie dann unter Verwendung einer Methode des (dh eines Befehls) als Arbeitsbereich Daten an a von ( nachdem das Modell die Aktualisierung des Anwendungsstatus abgeschlossen hat ).View
Controller
Controller
Controller
View
Model
Durch das Übergeben von Daten (Arrays, iterierbare Objekte usw.) bleibt die Kopplung zwischen
Model
undView
Instanzen locker . Wenn Sie dieModel
Instanz in das injizierenView
, lesen Sie Problem Nr. 1 oben.Denken Sie daran, dass
Views
es sich nach einer REST-Methode (Representation State Transfer Method) um HTML, JSON, Text, XML, HTTP-Header, YAML oder fast alles andere handeln kann .Der Schlüssel zum Verständnis, wie die Beziehung zwischen
Model
und verwaltet werden kann,Views
besteht darin, die Beziehung so zu sehen, wie sie ist, eins zu viele (potenziell)! Genau dafür wurde das Observer- Muster entwickelt.Während die meisten Setups jeweils nur eine Ansicht bearbeiten müssen, hindert nichts das MVC-Architekturmuster daran, mehrere Ansichten gleichzeitig zu aktualisieren! Die Arbeit mit herkömmlichen CRUD-Webanwendungen lässt die Leute eins zu eins denken , aber das ist das kleinste Beispiel dafür, wie das Observer-Muster funktionieren könnte ( eins zu viele ist das andere ).
Wenn Sie also eine
Model
oder mehrere hattenViews
, wird das potenzielle Problem , den gesamtenViews'
Implementierungscode zu aktualisieren , weil Sie etwas an derModel's
API / den Methoden geändert haben , jetzt akut .Übergeben Sie Daten an
Views
, nicht an Instanzen vonModels
.quelle