Dado o conceito de 'controladores magros, modelos gordos' e a aceitação geral de que o Views pode chamar diretamente o Models ao exigir dados para saída, deve-se considerar lidar com as partes de 'obter e exibir' as solicitações no Views e não no Controller? Por exemplo (tentativa de manter o 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');
}
}
Visão
<?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 mim, isso faz pelo menos algum sentido nos casos em que uma solicitação é essencialmente apenas uma Visualização. Por que o Controlador deve coletar e repassar os dados para o View quando ele pode apenas recuperá-lo? Isso deixa o Controlador aberto para processamento puramente no "nível de aplicativo" (por exemplo, tratamento de solicitações GET / POST, gerenciamento de direitos e permissões de acesso etc.), além de manter os modelos reutilizáveis e todas as outras coisas boas.
Se este exemplo fosse estendido para permitir que um usuário filtrasse os resultados, o Controlador apenas manipularia o POST do formulário e passaria os filtros para a Visualização, que solicitaria os dados novamente, desta vez com os filtros.
Essa é uma abordagem válida para o desenvolvimento de um aplicativo MVC? Ou estou negligenciando uma parte importante do papel que um Controlador deve desempenhar?
fonte
offers_model->get_latest()
ser feita? Adicionar isso a todos os métodos do controlador (como eu tentei tolamente antes) parece exagero e claramente seco.offers_model->get_latest()
umaProductViewModel
classe base ou algo semelhante.Não, isso não está correto. A exibição não pode chamar diretamente os modelos. As visualizações não devem ter acesso aos objetos Modelo, a menos que, por algum motivo, o programador tenha exposto esses objetos à Visualização.
Isso basicamente apaga o Controlador e derrota o ponto de tê-los.
O controlador não coleta os dados. O Modelo faz a coleta dos dados. O controlador decide se esses dados devem ser passados para a visualização. O View apenas faz a apresentação dos dados.
Não.
O Controlador verifica se os dados do POST são válidos, depois passa esses dados como opções para o Modelo, que consultaria a fonte de dados e retornaria os dados, e o Controlador os passaria para a Visualização.
O Controller opera como um manipulador de solicitações do navegador. Um despachante envia a solicitação para a ação de um controlador, que, por sua vez, espalha a solicitação para os Modelos. Os modelos contêm toda a lógica de negócios (essa é a parte mais importante) e devolvem os dados ao controlador. O controlador pode simplificar e ajustar os dados para facilitar a exibição do View.
O objetivo da Visualização é dissociar a estrutura e a dependência entre a apresentação do HTML e o DataSource. Enquanto isso pode ser difícil. As visualizações nem sempre apresentam dados que vieram diretamente de um modelo. O controlador geralmente adiciona dados extras relevantes.
Tenho certeza de que existem muitos tutoriais no MVC. Eu recomendo a leitura de alguns deles.
fonte
Achei sua pergunta muito interessante porque encontrei o mesmo problema ao aprender Python recentemente.
Enquanto as respostas dadas fazem um argumento convincente, pensei em acrescentar outra opinião que me deparei, na qual o View obtém o estado do Modelo sem passar pelo Controlador.
Não estou em posição de dizer qual das opiniões é "correta" e, para ser sincera, fico um pouco mais confusa depois de ler as respostas aqui e o artigo vinculado.
Texto completo do artigo aqui .
fonte
Outra coisa a considerar é que você parece ter carregado automaticamente
user_model
einvoice_model
permitir que a visualização os acesse. Para que isso funcione de maneira confiável, você provavelmente carrega automaticamente todos os seus modelos (porque$this->load->model()
apenas parece errado em uma exibição, não é ...)Fazer isso incha sua pilha desnecessariamente, carregando um monte de coisas que talvez nunca sejam usadas. Parte do motivo de ter vários modelos é permitir que você encapsule a lógica relacionada e carregue apenas o necessário para uma determinada tarefa.
Isso se parece com o CodeIgniter. Desenvolvi muito o desenvolvimento de CI e posso compartilhar por experiência pessoal que você realmente não deseja carregar automaticamente mais do que realmente precisa. Tente adicionar
$this->output->enable_profiler(TRUE);
o construtor de um controlador e mexer com carregamentos automáticos (incluindo auxiliares comodatabase
): você provavelmente verá uma mudança significativa nos tempos de carregamento e execução, mas principalmente na alocação de memória.fonte
load->model
na maioria dos controladores e métodos. Não usando uma função autoload adequada é uma das coisas que mais gostam sobre compatibilidade com versões anteriores do CI, mas isso é toda uma outra discussão ...A resposta curta é que a forma do seu exemplo de código é enganosamente intuitiva. Parece que este é um caminho "fácil de entender".
Problema # 1
Seus objetos
Model
eView
serão fortemente acoplados.Se você precisar adicionar ou remover métodos no
Model
, poderá ser necessário alterar o mesmoView
.Fundamentalmente, o MVC é derivado dos padrões Command e Observer . Você deseja um 'Modelo' independente que seja manipulado por meio de uma interface / API na qual ele
Controller
possa se conectar (ou seja, delegação).Freqüentemente, isso significa injetar
Model
eView
instâncias noController
e armazená-los como propriedades do referidoController
. Em seguida, usando um método daController
(ou seja, um comando) como área de trabalho, passe os dados para a aView
partir deModel
( depois que o `Modelo terminar de atualizar o estado do aplicativo ).Dados passam (arrays, objectos iteráveis, qualquer que seja) mantém acoplamento entre
Model
eView
instâncias solta . Se você injetar aModel
instância noView
, consulte o Problema nº 1 acima.Lembre-se,
Views
pode ser HTML, JSON, Texto, XML, cabeçalhos HTTP, YAML ou quase qualquer coisa, seguindo uma metodologia de transferência de estado de representação (REST) .Assim, a chave para compreender como gerir a relação entre o
Model
eViews
é ver a relação para o que é, um-para-muitos (potencialmente)! É exatamente isso que o padrão Observer foi projetado para realizar.Embora a maioria das configurações tenha apenas uma visão para se preocupar por vez, não há nada que impeça o padrão arquitetural do MVC de atualizar várias visualizações ao mesmo tempo! Trabalhar com aplicações CRUD web tradicionais faz com que as pessoas pensam em um one-to-one way, mas isso é o menor exemplo de como o padrão Observer poderia trabalhar ( um-para-muitos sendo o outro ).
Portanto, se você tivesse um
Model
e váriosViews
, a dor de cabeça em potencial de atualizar todo oViews'
código de implementação porque você alterou algo naModel's
API / métodos agora fica aguda .Passe dados para
Views
, não instâncias deModels
.fonte