Mam listę rozwijaną, która wyświetla wartości z tabeli do użytkownika końcowego. Chciałbym, aby te wartości były sortowane alfabetycznie.
Zgodnie z odpowiednim projektem MVC, na jakiej warstwie powinienem umieścić logikę sortowania: model, widok czy kontroler?
EDYCJA : W odpowiedzi na pytanie LarsH'a „Czy masz na myśli kod, który określa, jaki porządek sortowania jest wymagany? Czy kod wykonujący sortowanie?”, Odnosiłem się pierwotnie do kodu, który określa, jaki porządek sortowania jest pożądany.
asp.net-mvc
model-view-controller
Ryan Kohn
źródło
źródło
Odpowiedzi:
(Uwaga: ten cytat i cytat pochodzą z odpowiedzi @ dasblinkenlight , ale nie zgadzamy się z naszą interpretacją. Przeczytaj jego post i zdecyduj samodzielnie).
Zgodnie z opisem MVC ,
Logika sortowania (np. Komparator sortowania / algorytm sortowania) należy do modelu, ponieważ zawiera reguły biznesowe i dane o stanie. Ponieważ zmiana sposobu sortowania danych modelu należy do kategorii „zmień prezentację widoku modelu”, kontroler jest odpowiedzialny za „sortowanie” przez wywołanie metody model.changeSortedState ().
źródło
public void Sort(bool sortByDescending = false)
Jeśli fałsz sortuje rosnąco. Lub po prostu użyj dwóch różnych metod sortowania, jeśli logika jest bardzo różna.Kto kontroluje porządek sortowania?
(Z Wikipedii )
1) Naturalny porządek w samych danych:
Zamówienie jest częścią Modelu, więc powinno tam trafić. Surowe pobranie „wszystkich danych” zwróciłoby dane w kolejności posortowanej i nie ma interfejsu do wybierania kolejności sortowania.
2) Użytkownik powinien kontrolować sposób, w jaki widzi dane:
Widok zapewniłby interfejs (taki jak strzałki w górę / w dół), który współdziała z kontrolerem, a Model rozumie dane wystarczająco dobrze, aby wykonać żądane sortowanie danych. Jednak surowe pobieranie danych niekoniecznie musi być sortowane, w przeciwieństwie do (1).
W obu przypadkach,
Widok nie rozumie, że istnieje jakiś rodzaj, poza możliwością pokazania, który kierunek sortowania został wybrany. Nie umieszczaj tam logiki.
Małe zastrzeżenie
Funkcjonalność sortowania może działać wyłącznie w Widoku, w jednym przypadku (o którym myślę od ręki; może być więcej):
Sortowanie „głupie”, w którym wszystkie dane są już widoczne i nie musi wykorzystywać żadnej wiedzy o domenie do sortowania. Na przykład bardzo proste porównanie ciągów lub liczb. Nie jest to możliwe na przykład w wynikach wyszukiwania na stronie internetowej, gdy wyniki mogą być podzielone na wiele stron.
źródło
Zgodnie z opisem MVC ,
Zgodnie z tym logika sortowania należy do kontrolera, ponieważ zmiana sposobu sortowania danych modelu należy do kategorii „zmień sposób prezentacji modelu w widoku”.
EDYCJA: Aby wyjaśnić liczne nieporozumienia wyrażane w komentarzach, „logika sortowania” nie jest kodem, który wykonuje sortowanie; to kod definiuje sortowanie. Logika sortowania porównuje ze sobą poszczególne pozycje w celu ustalenia kolejności (np. Poprzez instancję
IComparator<T>
) lub zawiera logikę, która konstruuje obiekt, który ma być używany do porządkowania przez system zewnętrzny (np. Poprzez instancjęIOrderedQueryable<T>
). Ta logika należy do kontrolera, ponieważ wymaga wiedzy związanej z „biznesową” stroną aplikacji. Sortowanie jest całkowicie wystarczające, ale jest ono niezależne od kodu, który faktycznie wykonujeto. Kod, który sortuje, może znajdować się w Twoim widoku, w Twoim modelu lub nawet w warstwie trwałości, która stanowi kopię zapasową Twojego modelu (np. Twoja baza danych SQL).źródło
IComparer<T>
. Pozostała „standardowa mechanika” sortowania, w tym odzyskiwanie danych z modelu, zależy od poglądu.{Unknown, Pass, Fail}
. Ponadto załóżmy, żeUnknown
zawsze należy sortować jako ostatnie, niezależnie od kolejności rosnącej lub malejącej, którą wybrał użytkownik. Umieszczenie tej logiki w widoku powiedziałoby zbyt wiele o biznesowym charakterze danych wcode
polu. Widok nie powinien tego wiedzieć: wie tylko, że użytkownik wykonał gest „sortowania” (np. Kliknął nagłówek); reszta należy do kontrolera.Żadne z powyższych. Sortowanie jest logiką biznesową, a logika biznesowa nie należy do żadnego z trzech. Nie każdy fragment kodu w Twojej aplikacji będzie modelem, widokiem lub kontrolerem.
To, co zwykle robię w moich aplikacjach MVC, to warstwa usług, która wykonuje całą logikę biznesową. Metody w warstwie usług powinny mieć czyste, proste API z dobrze nazwanymi parametrami. Następnie możesz wywołać te metody ze swojego kontrolera, aby manipulować danymi w modelach.
W tym sensie sortowanie odbywa się „w kontrolerze”, ale sam kod, który wykonuje sortowanie, nie powinien być implementowany w kontrolerze, a jedynie wywoływany stamtąd.
źródło
Na pewno nie kontroler: wysyła komunikaty do przeglądania i modelowania, ale powinien wykonywać jak najmniej pracy. Jeśli użytkownik może zmienić sortowanie, to żądanie jest obsługiwane przez kontroler, informując o tym model lub widok.
Może Widok, jeśli jest to rzecz czysta. Jeśli aplikacja działa równie dobrze bez sortowania, to sortowanie jest tylko częścią reprezentacji i powinno być widoczne w widoku.
Jeśli porządkowanie jest nieodłączną częścią domeny, powinno znaleźć się w modelu.
źródło
Wybór jest więc - czy uważasz, że jest to część logiki biznesowej domeny lub logiki prezentacji.
Jeśli implementujesz odpowiedni MVC Model2 lub klasyczny wzorzec MVC, to powiedziałbym, że kolejność danych dostarczanych przez warstwę modelu powinna być wyzwalana przez żądanie widoku do warstwy modelu. Widok pyta o uporządkowane dane, dostarcza je warstwa modelu.
Ale ponieważ używasz interpretacji wzorca MVC w ASP.NET MVC, która jest nieco inna niż standardowa MVC - wystąpienie ViewModel powinno żądać uporządkowanych informacji z warstwy modelu (z jakiegoś powodu struktura ASP.NET uważa, że szablony powinny być wywoływane „widoki” i widoki należy nazywać „modelami widoków”… to dziwne).
źródło
Zwykle robiłbym to w kontrolerze, aby pozostać zgodnie ze wzorem, jak w innych odpowiedziach. Poniżej znajdziesz uzasadnienie.
Zastanawiałem się nad tym i czytałem odpowiedzi oraz związane z nimi materiały i mówiąc pragmatycznie, powiedziałbym, że zależy to na przykład od twojego wniosku:
Czy jest to średnia / duża aplikacja i / lub ma powiązanych z nią wiele UI (tj. Aplikacja Windows, interfejs sieciowy i interfejs telefonu).
Jeśli jest to dobrze zdefiniowana witryna internetowa z pojedynczym interfejsem użytkownika i używasz czegoś takiego jak EF Code First i nie masz lub nie masz zamiaru tworzyć warstwy usług i planujesz użyć prostej metody rozszerzenia, aby ją osiągnąć:
Jeśli jest taki sam jak powyższy, ALE nie można go zaimplementować z metodą rozszerzenia po wyjęciu z pudełka.
Podsumowując:
Odpowiedź dogmatyczna: warstwa usług
Pragmatyczna odpowiedź: Zwykle kontroler
źródło
Sugerowałbym sortowanie danych z tabeli - dane, które są wystarczająco małe, aby były przydatne na liście rozwijanej - powinny pochodzić z bazy danych już posortowanej za pomocą zapytania. Dla mnie to sprawia, że model jest miejscem, w którym stosowane jest sortowanie.
Jeśli jesteś zdeterminowany, aby sortować ręcznie, myślę, że są dobre argumenty za używaniem modelu lub kontrolera jako preferowanego miejsca dla logiki. Ograniczeniem byłby twój konkretny framework. Wolę zarządzać danymi wyłącznie w modelu. Używam kontrolera, aby poślubić dane (model) i prezentację (widok), tak jak zostałem (sam) nauczony.
źródło
Chociaż zasadniczo zgadzam się z ideą, że sortowanie jest logiką biznesową, ponieważ rozkładając je na pochodzenie, otrzymamy coś w rodzaju: „Klient chciałby, aby strona produktu była wyświetlana z obrazami posortowanymi według daty”, wtedy staje się jasne, że porządek sortowania danych zazwyczaj nie jest arbitralny - nawet jeśli nie ma sortowania, ponieważ nadal jest to decyzja biznesowa przez pominięcie (pusta lista jest nadal listą).
ALE ... Te odpowiedzi nie wydają się uwzględniać postępu w technologii ORM, mogę mówić tylko w odniesieniu do Entity Framework (unikajmy dyskusji o tym, czy to jest prawdziwy ORM, nie o to chodzi) od Microsoft jako tego właśnie używam, ale jestem pewien, że inne ORMy oferują podobną funkcjonalność.
Jeśli utworzę widok z silną typizacją dla klasy produktu przy użyciu MS MVC i Entity Framework i istnieje relacja klucza obcego między tabelą produktu i obrazu (np. obrazy podczas ich wyświetlania za pomocą czegoś takiego w widoku:
Wspomniano o konkretnej warstwie logiki biznesowej, której używam również do wykonywania 80% mojej logiki biznesowej, ale nie zamierzam zapisywać funkcji sortowania w mojej warstwie logiki biznesowej, która naśladuje coś, co pojawia się po wyjęciu z pudełka z Entity Framework.
Nie sądzę, że istnieje poprawna odpowiedź na to pytanie, poza tym, że tak. jeśli to możliwe, powinieneś ująć abstrakcyjną logikę biznesową, ale nie kosztem ponownego wynalezienia koła.
źródło
myList.OrderBy(x => x.CreationDate)
- naprawdę nie ma potrzeby wprowadzania żadnych niepotrzebnych dodatkowych warstw, aby to zrobić. Aby dodać do tego, co by zrobili, gdyby potrzebowali stronicowanych i posortowanych danych? Zapytaj całą tabelę, posortuj ją i zachowaj to, czego potrzebują? Wystarczy zadzwonićmyList.OrderBy(x => x.Date).Skip((page-1)*pageSize).Take(pageSize)
i nie zostaną odzyskane żadne niepotrzebne dane.Załóżmy, że masz witrynę MVC, witrynę WebForms i aplikację mobilną.
Jeśli chcesz, aby sortowanie było spójne między tymi warstwami prezentacji, powiedziałbym, że sortuj poza warstwą prezentacji. Służba byłaby dobrym kandydatem.
W przeciwnym razie zapisałbym tę logikę w modelu widoku. Czemu? Ponieważ będzie można go ponownie użyć i łatwo przetestować.
źródło
Z trzech, które wymieniłeś, powiedziałbym, że należy do kontrolera. Nie podoba mi się jednak umieszczanie tego rodzaju logiki w kontrolerze. Zwykle tworzę warstwę usług, z którą komunikuje się kontroler, która będzie odpowiedzialna za komunikację z magazynem danych i obsługę logiki sortowania. Jednak w przypadku małych aplikacji dobrze jest siedzieć w kontrolerze.
źródło
Jest to pytanie zadane z myślą o asp.net, ale ponieważ ktoś wspomniał o Railsach, pomyślałem, że byłoby interesujące rozważenie problemu w tym kontekście. W Railsach sortowanie wraz z pobieraniem danych jest wykonywane jako akcja kontrolera w sposób naturalny i dość powszechny, ponieważ struktura i interfejs API ActiveRecord / ActiveQuery obsługują to. Z drugiej strony można zdefiniować niestandardowy porządek sortowania dla elementów statycznych i umieścić go w modelu używanym przez kontroler, aby model mógł odgrywać rolę w logice sortowania, nawet jeśli nie wykonuje operację bezpośrednio. Cokolwiek to jest, można śmiało powiedzieć, że umieszczanie logiki sortowania jest generalnie niezadowolone.
Jestem trochę rozbawiony, że niektóre odpowiedzi są absolutnie przeciwne umieszczaniu tego rodzaju w kontrolerze lub modelu i uważam je za zbyt pedantyczne jak na mój gust, ale przypuszczam, że zależy to od natury używanego frameworka i zwykłych konwencji związanych z to. Zgadzam się również z komentarzem Billa K., że ważniejsze jest przede wszystkim rozłąka.
źródło