Biorąc pod uwagę koncepcję „chudych kontrolerów, grubych modeli” i ogólną akceptację, że widoki mogą bezpośrednio wywoływać modele, gdy wymagają danych do danych wyjściowych, czy należy rozważyć obsługę części „pobierania i wyświetlania” żądań w widokach, a nie kontrolera? Na przykład (próbował zachować kod dość ogólny):
Kontroler
<?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');
}
}
Widok
<?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>
Dla mnie ma to przynajmniej sens w przypadkach, w których żądanie jest zasadniczo tylko widokiem. Dlaczego administrator powinien zbierać i przekazywać dane do widoku, skoro może je po prostu odzyskać? To pozostawia kontroler otwarty na przetwarzanie „na poziomie aplikacji” (np. Obsługę żądań GET / POST, zarządzanie prawami dostępu i uprawnieniami itp.), A także zachowanie Modelów wielokrotnego użytku i innych dobrych rzeczy.
Jeśli ten przykład został rozszerzony, aby umożliwić użytkownikowi filtrowanie wyników, kontroler po prostu obsłużyłby test POST z formularza i przekazał filtry do widoku, który następnie zażądałby danych ponownie, tym razem z filtrami.
Czy jest to poprawne podejście do tworzenia aplikacji MVC? Czy też pomijam ważną rolę, jaką powinien odgrywać Kontroler?
źródło
offers_model->get_latest()
? Dodanie tego do każdej metody w kontrolerze (jak wcześniej głupio próbowałem) wydaje się przesadą i wyraźnie pozbawione SUSZENIA.offers_model->get_latest()
doProductViewModel
klasy bazowej lub coś podobnego.Nie. To nie jest poprawne. Widok nie może bezpośrednio wywoływać modeli. Widoki nie powinny mieć dostępu do obiektów modelu, chyba że z jakiegoś powodu programista wystawił te obiekty na widok.
To zasadniczo wymazuje kontroler i pokonuje sens posiadania go.
Administrator nie zbiera danych. Model zbiera dane. Administrator decyduje, czy dane te należy przekazać do widoku. Widok wykonuje tylko prezentację danych.
Nie.
Kontroler sprawdza, czy dane POST są poprawne, a następnie przekazuje te dane jako opcje do modelu, który następnie wysyła zapytanie do źródła danych i zwraca dane, a kontroler przekazuje je do widoku.
Kontroler działa jako moduł obsługi żądań przeglądarki. Dyspozytor wysyła żądanie do akcji kontrolera, która z kolei rozsyła żądanie do modeli. Modele zawierają całą logikę biznesową (jest to gruba część) i zwracają dane administratorowi. Kontroler może następnie uprościć i dostosować dane, aby widok mógł je łatwiej wyświetlić.
Celem widoku jest rozdzielenie struktury i zależności między prezentacją HTML a źródłem danych. Chociaż może to być trudne. Widoki nie zawsze prezentują dane pochodzące bezpośrednio z modelu. Administrator często dodaje dodatkowe istotne dane.
Jestem pewien, że na MVC jest wiele samouczków. Poleciłbym przeczytać niektóre z nich.
źródło
Uważam, że twoje pytanie jest bardzo interesujące, ponieważ podczas nauki języka Python napotkałem ten sam problem.
Choć udzielone odpowiedzi stanowią przekonujący argument, pomyślałem, że dodam kolejną opinię, w której natknąłem się na widok, w którym widok uzyskuje stan modelu bez przechodzenia przez kontroler.
Nie jestem w stanie powiedzieć, która z opinii jest „słuszna”, i szczerze mówiąc, jestem trochę bardziej zdezorientowany po przeczytaniu tutaj odpowiedzi i powiązanego artykułu.
Pełny tekst artykułu tutaj .
źródło
Inną rzeczą do rozważenia jest to, że prawdopodobnie załadowałeś ją automatycznie
user_model
iinvoice_model
pozwalasz widokowi na dostęp do nich. Aby działało to niezawodnie, prawdopodobnie automatycznie ładujesz wszystkie swoje modele (ponieważ$this->load->model()
po prostu wygląda źle w widoku, prawda?)Robiąc to niepotrzebnie nadymasz swój stos, ładując kilka rzeczy, które mogą nigdy nie zostać wykorzystane. Jednym z powodów posiadania wielu modeli jest umożliwienie enkapsulacji powiązanej logiki i załadowanie tylko tego, czego potrzebujesz do danego zadania.
To wygląda jak CodeIgniter. Dużo opracowałem CI i mogę podzielić się z własnego doświadczenia, że tak naprawdę nie chcesz automatycznie ładować więcej, niż naprawdę musisz. Spróbuj dodać
$this->output->enable_profiler(TRUE);
konstruktora kontrolera i bawić się przy autoloadach (w tym pomocnikach takich jakdatabase
): prawdopodobnie zauważysz znaczącą zmianę w czasie ładowania i wykonania, ale szczególnie w alokacji pamięci.źródło
load->model
w większości kontrolerów i metod. Niewłaściwe użycie funkcji automatycznego ładowania jest jedną z rzeczy, których najbardziej nie lubię w kompatybilności wstecznej CI, ale to zupełnie inna dyskusja ...Krótka odpowiedź brzmi: forma próbki kodu jest zwodniczo intuicyjna. Wydawałoby się, że jest to droga „bezproblemowa”.
Problem nr 1
Twoje
Model
iView
przedmioty będą ściśle powiązane.Jeśli kiedykolwiek będziesz musiał dodać lub usunąć metody w
Model
, być może będziesz musiał odpowiednio zmienićView
.Zasadniczo MVC jest pozbawione wzorców Dowodzenia i Obserwatora . Chcesz niezależnego „Modelu”, którym można manipulować za pomocą interfejsu / interfejsu API , do którego
Controller
można się podłączyć (tj. Delegowanie).Często oznacza to wstrzykiwanie
Model
iView
instancje doController
i przechowywanie ich jako właściwości wspomnianychController
. Następnie, używając metodyController
(tj. Polecenia) jako obszaru roboczego, przekaż dane doView
zModel
( po zakończeniu `Modelu aktualizacji stanu aplikacji ).Uboczny danych (tablice, iterable obiekty, cokolwiek) utrzymuje sprzęgających pomiędzy
Model
iView
instancje luźne . Jeśli wstrzyknieszModel
instancję doView
, zobacz problem nr 1 powyżej.Pamiętaj, że
Views
może to być HTML, JSON, Tekst, XML, nagłówki HTTP, YAML lub prawie wszystko, zgodnie z metodologią transferu stanu reprezentacji (REST) .Zatem kluczem do zrozumienia, jak zarządzać relacją między
Model
i,Views
jest dostrzeżenie relacji takiej, jaka jest, jeden do wielu (potencjalnie)! Właśnie do tego został zaprojektowany wzór Observer .Podczas gdy większość konfiguracji ma tylko jeden widok, którym można się zajmować na raz, nic nie stoi na przeszkodzie, aby wzorzec architektoniczny MVC aktualizował wiele widoków jednocześnie! Praca z tradycyjnymi aplikacjami sieciowymi CRUD sprawia, że ludzie myślą w sposób jeden do jednego , ale jest to najmniejszy przykład tego, w jaki sposób mógłby działać wzorzec Observer ( jeden do wielu ).
Tak więc, jeśli miałeś jeden
Model
i wieleViews
, potencjalny ból głowy związany z aktualizacją całegoViews'
kodu implementacji, ponieważ zmieniłeś coś wModel's
API / metodach, staje się teraz ostry .Przekaż dane
Views
, a nie wystąpieniaModels
.źródło