Compte tenu du concept de `` contrôleurs maigres, de gros modèles '' et de l'acceptation générale que les vues peuvent appeler directement les modèles lors de la demande de données pour la sortie, devrait-on envisager de gérer les parties `` obtenir et afficher '' des demandes dans les vues et non le contrôleur? Par exemple (a tenté de garder le code assez générique):
Manette
<?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');
}
}
Vue
<?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>
Pour moi, cela a au moins un certain sens dans les cas où une demande est essentiellement juste une vue. Pourquoi le contrôleur devrait-il collecter et transmettre les données à la vue alors qu'il peut simplement les récupérer lui-même? Cela laisse le contrôleur ouvert pour un traitement purement «au niveau de l'application» (par exemple, la gestion des demandes GET / POST, la gestion des droits d'accès et des autorisations, etc.) ainsi que la conservation des modèles réutilisables et toutes les autres bonnes choses.
Si cet exemple était étendu pour permettre à un utilisateur de filtrer les résultats, le contrôleur manipulerait simplement le POST du formulaire et transmettrait les filtres à la vue, qui demanderait à nouveau les données, cette fois avec les filtres.
Est-ce une approche valable pour développer une application MVC? Ou est-ce que je néglige une partie importante du rôle qu'un contrôleur devrait jouer?
la source
offers_model->get_latest()
être effectué? L'ajout de cela à chaque méthode du contrôleur (comme je l'ai déjà bêtement tenté) semble exagéré et nettement non SEC.offers_model->get_latest()
à uneProductViewModel
classe de base ou quelque chose de similaire.Non, ce n'est pas correct. La vue ne peut pas appeler directement les modèles. Les vues ne doivent pas avoir accès aux objets du modèle, sauf si, pour une raison quelconque, le programmeur a exposé ces objets à la vue.
Cela efface fondamentalement le contrôleur et défait le point de les avoir.
Le contrôleur ne collecte pas les données. Le modèle effectue la collecte des données. Le contrôleur décide si ces données doivent être transmises à la vue. La vue ne fait que la présentation des données.
Non.
Le contrôleur vérifie si les données POSTées sont valides, il transmet ensuite ces données en tant qu'options au modèle, qui interroge ensuite la source de données et renvoie les données, et le contrôleur les transmet à la vue.
Le contrôleur fonctionne comme un gestionnaire des demandes du navigateur. Un répartiteur envoie la demande à l'action d'un contrôleur, qui à son tour, diffuse la demande aux modèles. Les modèles contiennent toute la logique métier (c'est la partie grasse) et rendent les données au contrôleur. Le contrôleur peut alors simplifier et ajuster les données afin qu'il soit plus facile pour la vue de les présenter.
Le point de vue est de découpler la structure et la dépendance entre la présentation du HTML et le DataSource. Bien que cela puisse être difficile. Les vues ne présentent pas toujours des données provenant directement d'un modèle. Le contrôleur ajoute souvent des données supplémentaires pertinentes.
Je suis sûr qu'il existe de nombreux tutoriels sur MVC. Je recommanderais de lire certains d'entre eux.
la source
J'ai trouvé votre question très intéressante car j'ai rencontré le même problème lors de mon apprentissage de Python récemment.
Bien que les réponses données constituent un argument convaincant, j'ai pensé ajouter une autre opinion que j'ai rencontrée dans laquelle la vue obtient l'état du modèle sans passer par le contrôleur.
Je ne suis pas en mesure de dire laquelle des opinions est "correcte", et pour être honnête, je suis un peu plus confus après avoir lu les réponses ici et l'article lié.
Texte complet de l'article ici .
la source
Une autre chose à considérer est que vous semblez avoir chargé automatiquement le
user_model
etinvoice_model
permettre à la vue d'y accéder. Pour que cela fonctionne de manière fiable, vous devez probablement charger automatiquement tous vos modèles (car cela$this->load->model()
ne semble pas correct dans une vue, n'est-ce pas ...)Faire cela gonfle inutilement votre pile en chargeant un tas de choses qui pourraient ne jamais être utilisées. Une partie de la raison d'avoir plusieurs modèles est de vous permettre d'encapsuler la logique associée et de charger uniquement ce dont vous avez besoin pour une tâche donnée.
Cela ressemble à CodeIgniter. J'ai fait beaucoup de développement de CI et je peux partager par expérience personnelle que vous ne voulez vraiment pas charger automatiquement plus que vous ne l'avez vraiment. Essayez d'ajouter
$this->output->enable_profiler(TRUE);
le constructeur d'un contrôleur et de jouer avec les chargements automatiques (y compris les aides commedatabase
): vous verrez probablement un changement significatif dans les temps de chargement et d'exécution, mais surtout dans l'allocation de mémoire.la source
load->model
dans la plupart des contrôleurs et des méthodes. Ne pas utiliser une fonction de chargement automatique appropriée est l'une des choses que je n'aime pas le plus dans la rétrocompatibilité de CI, mais c'est une toute autre discussion ...La réponse courte est que la forme de votre exemple de code est trompeusement intuitive. Il semblerait que ce soit une solution «facile à l'esprit».
Problème n ° 1
Vos objets
Model
etView
seront étroitement liés.Si vous devez ajouter ou supprimer des méthodes dans le
Model
, vous devrez peut-être modifier le enView
conséquence.Fondamentalement, MVC est dérivé des modèles de commandement et d' observation . Vous voulez un «modèle» indépendant qui est manipulé via une interface / API à laquelle le
Controller
peut se connecter (c'est-à-dire la délégation).Fréquemment, cela signifie injecter
Model
etView
instances dans unController
et les stocker en tant que propriétés duditController
. Ensuite, en utilisant une méthode deController
(c'est-à-dire une commande) comme zone de travail, transmettez les données à unView
deModel
(une fois que le `Modèle a terminé la mise à jour de l'état de l'application ).La transmission de données (tableaux, objets itérables, peu importe) maintient le couplage entre les instances
Model
et lâche . Si vous injectez l' instance dans le , consultez le problème n ° 1 ci-dessus.View
Model
View
Rappelez-vous,
Views
pourrait être HTML, JSON, texte, XML, en-têtes HTTP, YAML ou presque n'importe quoi, suivant une méthodologie de transfert d'état de représentation (REST) .Ainsi, la clé pour comprendre comment gérer la relation entre le
Model
etViews
est de voir la relation pour ce qu'elle est, un à plusieurs (potentiellement)! C'est exactement ce que le modèle Observer a été conçu pour accomplir.Alors que la plupart des configurations n'ont qu'une seule vue à traiter à la fois, rien n'empêche le modèle architectural MVC de mettre à jour plusieurs vues à la fois! Travailler avec des applications Web traditionnelles CRUD fait réfléchir les gens dans un one-to-one chemin, mais qui est le plus petit exemple de la façon dont le modèle d'observateur pourrait travailler ( un à plusieurs étant l'autre ).
Ainsi, si vous en aviez un
Model
et plusieursViews
, le mal de tête potentiel de la mise à jour de tout leViews'
code d'implémentation parce que vous avez changé quelque chose dans l'Model's
API / méthodes devient maintenant aigu .Passez les données à
Views
, pas les instances deModels
.la source