In MVC, può / dovrebbe il recupero dei dati di base dal modello essere fatto nella vista?

10

Dato il concetto di 'skinny controller, modelli grassi' e l'accettazione generale che Views può chiamare direttamente su Models quando richiede dati per l'output, si dovrebbe prendere in considerazione la gestione delle parti 'get and display' di richieste all'interno delle viste e non del controller? Ad esempio (tentato di mantenere il codice abbastanza generico):

Regolatore

<?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');

    }

}

Visualizza

<?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>

Per me, questo ha almeno un senso nei casi in cui una richiesta è essenzialmente solo una vista. Perché il Controller deve raccogliere e trasmettere i dati alla Vista quando può recuperarli autonomamente? Ciò lascia aperto il controller solo per l'elaborazione a livello di applicazione (ad esempio gestendo richieste GET / POST, gestendo i diritti di accesso e le autorizzazioni ecc.) E mantenendo i modelli riutilizzabili e tutte le altre cose buone.

Se questo esempio è stato esteso per consentire a un utente di filtrare i risultati, il controllore gestirà semplicemente il POST dal modulo e passerà i filtri alla vista, che richiederebbe di nuovo i dati, questa volta con i filtri.

Questo è un approccio valido allo sviluppo di un'applicazione MVC? Oppure sto trascurando una parte importante del ruolo che un Controller dovrebbe svolgere?

    
posta Adam Westbrook 31.01.2013 - 18:49
fonte

4 risposte

16

Sì, tecnicamente può essere fatto. No, non dovrebbe essere fatto. E sì, ti manca un po 'di ciò che il controller è lì.

Il controller è lì per disaccoppiare la vista dal modello. Il disaccoppiamento è utile perché dovresti guardare il codice View as quasi-throw-away. Man mano che la tecnologia dell'interfaccia utente cambia, si desidera ridurre al minimo la rilavorazione necessaria per generare una nuova vista. Il controller abilita tale disaccoppiamento e fornisce un posto per il codice che vivrà attraverso le tecnologie dell'interfaccia utente.

Funziona anche al contrario se è necessario aggiungere o modificare il modello. Tutte le modifiche a monte saranno contenute all'interno del Controller e le tue Viste saranno lasciate in pace.

L'altro rischio è che mentre la vista è molto semplice ora , hai meno garanzie che rimarrà così semplice per tutta la sua vita. Chiamando il modello direttamente dalla (molto semplice) vista, hai aperto un po 'la porta per permettere a ulteriori cattive pratiche di insinuarsi in seguito quando la semplice visualizzazione deve diventare non molto semplice. Uno sviluppatore futuro sarà tentato di effettuare più chiamate Model dalla vista non molto semplice invece di refactoring del codice e interazione con un controller.

    
risposta data 31.01.2013 - 19:45
fonte
6

Given the concept of 'skinny controllers, fat models' and the general acceptance that Views can directly call on Models when requiring data for output

No. Questo non è corretto. La vista non può chiamare direttamente su Modelli. Le viste non dovrebbero avere accesso agli oggetti del modello, a meno che per qualche motivo il programmatore non abbia esposto tali oggetti alla vista.

should one consider handling the 'get and display' parts of requests within the Views and not the Controller?

In pratica cancella il controller e sconfigge il punto di averli.

Why should the Controller have to collect and pass on the data to the View when it can just retrieve it itself?

Il controller non raccoglie i dati. Il modello esegue la raccolta dei dati. Il controller decide se questi dati devono essere passati alla vista. La vista fa solo la presentazione dei dati.

If this example was extended to allow a user to filter the results, the Controller would just handle the POST from the form and pass the filters to the View, which would then request the data again, this time with the filters.

No.

Il Controllore controlla se i dati POSTed sono validi, quindi passa questi dati come opzioni al Modello, che quindi interrogano l'origine dati e restituiscono i dati, e il Controllore lo passa alla Vista.

Is this a valid approach to developing an MVC application? Or am I overlooking an important part of the role a Controller should play?

Il controller funziona come gestore per le richieste del browser. Un dispatcher invia la richiesta all'azione di un controllore, che a sua volta distribuisce la richiesta ai Modelli. I Modelli contengono tutta la logica aziendale (questa è la parte più grossa) e restituiscono i dati al controller. Il controller può quindi semplificare e adattare i dati in modo che sia più semplice per la visualizzazione presentarli.

Il punto della vista è quello di disaccoppiare la struttura e la dipendenza tra la presentazione di HTML e DataSource. Mentre questo può essere difficile. Le viste non sempre presentano i dati che provengono direttamente da un modello. Il controller spesso aggiunge dati extra rilevanti.

Sono sicuro che ci sono molti tutorial su MVC. Consiglierei di leggerne alcuni.

    
risposta data 31.01.2013 - 19:57
fonte
3

Ho trovato la tua domanda molto interessante perché ho incontrato lo stesso problema durante l'apprendimento di Python di recente.

Mentre le risposte fornite costituiscono un argomento convincente, ho pensato di aggiungere un'altra opinione in cui la View ha ottenuto lo stato del modello senza passare per il controller.

MVC

It is important to note that both the view and the controller depend on the model. However, the model depends on neither the view nor the controller. This is one the key benefits of the separation. This separation allows the model to be built and tested independent of the visual presentation. The separation between view and controller is secondary in many rich-client applications, and, in fact, many user interface frameworks implement the roles as one object. In Web applications, on the other hand, the separation between view (the browser) and controller (the server-side components handling the HTTP request) is very well defined.

Model-View-Controller is a fundamental design pattern for the separation of user interface logic from business logic. Unfortunately, the popularity of the pattern has resulted in a number of faulty descriptions. In particular, the term "controller" has been used to mean different things in different contexts. Fortunately, the advent of Web applications has helped resolve some of the ambiguity because the separation between the view and the controller is so apparent.

In Application Programming in Smalltalk-80: How to use Model-View-Controller (MVC) [Burbeck92], Steve Burbeck describes two variations of MVC: a passive model and an active model.

The passive model is employed when one controller manipulates the model exclusively. The controller modifies the model and then informs the view that the model has changed and should be refreshed (see Figure 2). The model in this scenario is completely independent of the view and the controller, which means that there is no means for the model to report changes in its state. The HTTP protocol is an example of this. There is no simple way in the browser to get asynchronous updates from the server. The browser displays the view and responds to user input, but it does not detect changes in the data on the server. Only when the user explicitly requests a refresh is the server interrogated for changes.

MVC - Passive Model

Non sono in grado di dire quale delle opinioni è "giusta", e ad essere sincero, sono un po 'più confuso dopo aver letto le risposte qui e l'articolo collegato.

Testo integrale dell'articolo qui .

    
risposta data 02.02.2013 - 12:43
fonte
1

Un'altra cosa da considerare è che sembra che tu abbia caricato automaticamente user_model e invoice_model per consentire alla vista di accedervi. Affinché funzioni in modo affidabile, probabilmente esegui il caricamento automatico di tutti dei tuoi modelli (perché $this->load->model() sembra solo sbagliato in una vista, non è così ...)

Fare questo aumenta inutilmente lo stack caricando un sacco di cose che potrebbero non essere mai utilizzate. Parte del motivo per cui esistono più modelli è consentire all'utente di incapsulare la logica correlata e caricare solo ciò che è necessario per una determinata attività.

Questo sembra CodeIgniter. Ho fatto un sacco di sviluppo di CI e posso condividere con l'esperienza personale che non si vuole caricare automaticamente più di quanto sia necessario. Prova ad aggiungere $this->output->enable_profiler(TRUE); nel costruttore di un controller e mantieni il caricamento automatico (inclusi helper come database ): probabilmente noterai un cambiamento significativo nei tempi di caricamento e esecuzione, ma specialmente nell'allocazione di memoria.

    
risposta data 31.01.2013 - 21:15
fonte

Leggi altre domande sui tag