Dado el concepto de 'controladores flacos, modelos gordos' y la aceptación general de que las Vistas pueden llamar directamente a los Modelos cuando requieren datos para la salida, ¿debería uno considerar manejar las partes de 'obtener y mostrar' de las solicitudes dentro de las Vistas y no el Controlador? Por ejemplo (intentó mantener el código bastante genérico):
Controlador
<?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');
}
}
Ver
<?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>
Para mí, esto tiene al menos algún sentido en los casos en que una solicitud es esencialmente solo una Vista. ¿Por qué el controlador debe recopilar y transmitir los datos a la vista cuando solo puede recuperarlos? Esto deja al Controlador abierto para el procesamiento puramente de 'Nivel de aplicación' (por ejemplo, manejo de solicitudes GET / POST, administración de derechos de acceso y permisos, etc.), así como para mantener los Modelos reutilizables y todas las demás cosas buenas.
Si este ejemplo se extendiera para permitir que un usuario filtre los resultados, el Controlador solo manejaría la POST desde el formulario y pasaría los filtros a la Vista, que luego solicitaría nuevamente los datos, esta vez con los filtros.
¿Es este un enfoque válido para desarrollar una aplicación MVC? ¿O estoy pasando por alto una parte importante del papel que debe desempeñar un controlador?
fuente
offers_model->get_latest()
? Agregar esto en cada método en el controlador (como he intentado tontamente antes) parece excesivo y claramente SECO.offers_model->get_latest()
a unaProductViewModel
clase base o algo similar.No esto no es correcto. Ver no puede llamar directamente a Modelos. Las vistas no deberían tener acceso a los objetos del Modelo, a menos que por alguna razón el programador haya expuesto esos objetos a la Vista.
Básicamente, eso borra el Controlador y anula el punto de tenerlos.
El controlador no recopila los datos. El modelo hace la recolección de los datos. El controlador decide si estos datos deben pasarse a la vista. La vista solo hace la presentación de los datos.
No.
El Controlador verifica si los datos PUBLICADOS son válidos, luego pasa estos datos como opciones al Modelo, que luego consultaría la fuente de datos y devolvería los datos, y el Controlador los pasa a la Vista.
El controlador funciona como un controlador de las solicitudes del navegador. Un despachador envía la solicitud a la acción de un controlador, que a su vez, extiende la solicitud a los Modelos. Los modelos contienen toda la lógica empresarial (esta es la parte importante) y devuelven los datos al controlador. El controlador puede entonces simplificar y ajustar los datos para que sea más fácil para la Vista presentarlos.
El punto de vista es desacoplar la estructura y la dependencia entre la presentación de HTML y DataSource. Si bien esto puede ser difícil. Las vistas no siempre presentan datos que provienen directamente de un modelo. El controlador a menudo agrega datos adicionales que son relevantes.
Estoy seguro de que hay muchos tutoriales en MVC. Recomiendo leer algunos de ellos.
fuente
Su pregunta me pareció muy interesante porque me encontré con el mismo problema mientras aprendía Python recientemente.
Si bien las respuestas dadas son un argumento convincente, pensé que agregaría otra opinión que encontré en la que la Vista obtiene el estado del Modelo sin pasar por el Controlador.
No estoy en condiciones de decir cuál de las opiniones es "correcta", y para ser honesto, estoy un poco más confundido después de leer las respuestas aquí y el artículo vinculado.
Texto completo del artículo aquí .
fuente
Otra cosa a considerar es que parece haber cargado automáticamente
user_model
yinvoice_model
permitir que la vista acceda a ellos. Para que esto funcione de manera confiable, probablemente cargue automáticamente todos sus modelos (porque$this->load->model()
simplemente se ve mal en una vista, ¿no es así?)Hacer esto hincha innecesariamente tu pila al cargar un montón de cosas que quizás nunca se usen. Parte de la razón para tener múltiples modelos es permitirle encapsular la lógica relacionada y cargar solo lo que necesita para una tarea determinada.
Esto se parece a CodeIgniter. He desarrollado mucho CI y puedo compartir por experiencia personal que realmente no quieres cargar más de lo que realmente debes. Intente agregar
$this->output->enable_profiler(TRUE);
el constructor de un controlador y jugar con cargas automáticas (incluidos los ayudantesdatabase
): probablemente verá un cambio significativo en los tiempos de carga y ejecución, pero especialmente en la asignación de memoria.fuente
load->model
en la mayoría de los controladores y métodos. No usar una función de carga automática adecuada es una de las cosas que más me disgustan de la compatibilidad con versiones anteriores de CI, pero esa es otra discusión ...La respuesta corta es que la forma de su muestra de código es engañosamente intuitiva. Parece que este es un camino "fácil de pensar".
Problema # 1
Tu
Model
yView
objetos estarán estrechamente acoplados.Si alguna vez tiene que agregar o quitar métodos en el
Model
, entonces es posible que tenga que modificarlos enView
consecuencia.Básicamente, MVC se deriva de los patrones de Comando y Observador . Desea un 'Modelo' independiente que se manipule a través de una interfaz / API en la que
Controller
pueda engancharse (es decir, delegación).Con frecuencia, esto significa inyectar
Model
eView
instancias enController
ay almacenarlas como propiedades de dichoController
. Luego, utilizando un método deController
(es decir, un comando) como área de trabajo, pase datos a aView
desdeModel
( después de que el `Modelo haya terminado de actualizar el estado de la aplicación ).Datos que pasan (arrays, objetos iterables, lo que sea) mantiene al tanto de acoplamiento entre
Model
yView
casos pierden . Si inyecta laModel
instancia en elView
, vea el Problema # 1 arriba.Recuerde,
Views
podría ser HTML, JSON, Texto, XML, encabezados HTTP, YAML o casi cualquier cosa, siguiendo una metodología de transferencia de estado de representación (REST) .Por lo tanto, la clave para comprender cómo gestionar la relación entre
Model
yViews
es ver la relación por lo que es, ¡ uno a muchos (potencialmente)! Esto es exactamente para lo que se diseñó el patrón Observer .Si bien la mayoría de las configuraciones solo tienen que ver una vista a la vez, ¡no hay nada que impida que el patrón arquitectónico MVC actualice varias vistas a la vez! Uso de aplicaciones CRUD web tradicionales hace que la gente piensa en un uno-a-uno manera, pero eso es el ejemplo más pequeño de cómo el patrón de observador podría trabajar ( uno-a-muchos es el otro ).
Por lo tanto, si tenía uno
Model
y múltiplesViews
, el potencial dolor de cabeza de actualizar todo elViews'
código de implementación porque cambió algo en laModel's
API / métodos ahora se agudiza .Pase datos a
Views
, no instancias deModels
.fuente