ASP.NET MVC - dwa modele w jednym widoku a dobre praktyki

0

Zaistniała mi ostatnio potrzeba umieszczenia danych z dwóch modeli w jednym widoku. Rozwiązałem to w ten sposób, że stworzyłem sobie ViewModel, który wygląda mniej więcej tak:

public class CompanyViewModel
    {
        public IEnumerable<HighElectrican.Models.CompanyInformations> companyInf { get;set; }
        public IEnumerable<HighElectrican.Models.Review> review { get;set; }
    }
 

Przestrzeń nazw tego modelu to ViewModels.
W miejscu, w którym wyświetlam dane z tego modelu do tabeli odnoszę się do przestrzeni nazw:

@model IEnumerable<HighElectrican.Models.Review> 

Czyli nie do ViewModelu, co ułatwia sprawę. Kiedy jednak chcę stworzyć metodę, która zapisuje dane do bazy muszę się odnieść do niego w taki sposób:

 @model HighElectrican.ViewModels.CompanyViewModel

a każde pole do edycji wygląda wtedy tak:

@Html.EditorFor(m => m.review.First().name 

i tutaj mam pytanie: czy dobrze się do tego odnoszę? Co prawda to działa, ale czy tak się powinno to robić?
Widok ten jest generowany jako partialview w głownym widoku.

Nie mogę jednak metody kontrolera powiązać z tym widokiem, dlatego to

 @model HighElectrican.ViewModels.CompanyViewModel

muszę wpisać ręcznie a wydaje mi się, że tak nie powinno się robić.

Metoda akcji głowneg widoku wygląda tak:

 public ActionResult Index()
        {
            // ViewModel vm = new ViewModel();
            CompanyViewModel vm = new CompanyViewModel();
            vm.companyInf = db.companyInformations.ToList();
            vm.review = db.reviews.ToList();
            return View(vm);
           // return View();
        }

Jak mogę przenieść wczytanie danych z bazy do modelu do kontrolera od widoku Review? Chyba,że może to pozostać w tym? Jak myślicie?

0

Nie wiem czy dobrze Ciebie zrozumiałem, także wybacz proszę, jeśli odpowiedź nie będzie ściśle dotyczyła Twojego problemu.
Generalnie zasada jest taka, że do jednego widoku istnieje jeden model. Także fakt stworzenia przez Ciebie jednego ViewModelu jest jak najbardziej słuszną drogą. Oczywiście PartialView może mieć inny viewModel niż widok główny.
Ale być może tutaj problem jest w nie do końca dobrym zamodelowaniu problemu. Po Twoim ViewModelu widzę, że chcesz wyświetlić listę firm i listę ocen (tych firm?). Czy kolekcje companyInfo i review są ze sobą jakoś powiązane? Jeśli jedna firma (z kolekcji companyInfo) ma przypisane swoje review, wówczas lepiej będzie przenieść kolekcję review do klasy CompanyInformations. Pytanie też, czy koniecznie companyInfo i review muszą obie być kolekcjami/tablicami?
Co ma przedstawiać widok?

0

Wydaje mi się że nie do końca rozumiesz jak działa EditorFor przekazujesz do niego tylko wskazanie na właściwość nic więcej.
czyli

EditorFor(m => m.JakasWlasciwosc) 

jest jedynym poprawnym wywołaniem. na podstawie typu właściwości dobierana jest "kontrolka" na podstawie nazwy właściwości jej nazwa/id która potem jest wykorzystana przy interpretacji wywołania typu POST.
Przychylam się do wypowiedzi poprzednika żebyś opisał (a najlepiej narysował) co chcesz osiągnąć.

0

Generalnie moją intencją było w jednym widoku wykorzystanie dwóch modeli - wyświetlenie danych dla dwóch różnych modeli.
Wyczytałem, że mogę to osiągnąć tworząc właśnie ViewModel, ale podobno da się też jakoś dzięki PartialView - w jaki sposób?

0

Coś chyba zakręciłeś, pytanie czy chcesz:
a) wykorzystać jeden widok np. do przedstawienia osoby i firmy (mogą się zdarzyć moduły w których interesuje nas tylko nazwa i adres zarówno osoba jak i firma te cechy posiadają)
b) chcesz w jednym widoku pokazać listę osób obok listy firm

0

W jednym widoku pokazać listę osób obok listy firm przy czym Firma i Osoba to dwa różne modele.

0

Możesz zostawić ten viewModel, który stworzyłeś. Niech on jest modelem dla widoku.
W widoku tym możesz zrobić dwie pętle foreach:

  1. jedna dla firm: foreach(CompanyInfo ci in Model.companyInf)
  2. druga: foreach(Review review in Model.review)
    Wewnątrz w zależności w jaki sposób chcesz zaprezentować dane, "wypisujesz" je na ekranie.

Alternatywą jest zrobienie dwóch PartialView, przekazując do jednego kolekcję CompanyInfo z modelu, do drugiego kolekcję Review, które dla tych PartialView będą modelem.

0
michal84 napisał(a):

Możesz zostawić ten viewModel, który stworzyłeś. Niech on jest modelem dla widoku.
W widoku tym możesz zrobić dwie pętle foreach:

  1. jedna dla firm: foreach(CompanyInfo ci in Model.companyInf)
  2. druga: foreach(Review review in Model.review)
    Wewnątrz w zależności w jaki sposób chcesz zaprezentować dane, "wypisujesz" je na ekranie.

Alternatywą jest zrobienie dwóch PartialView, przekazując do jednego kolekcję CompanyInfo z modelu, do drugiego kolekcję Review, które dla tych PartialView będą modelem.

@michal84
A czy przy podejściu z PartialView trzeba tworzyć ViewModel? Bo troszkę mi pomieszałeś - własnie tak teraz mam zrobione..

0

Wybacz, że namieszałem Tobie :).
Dla PartialView nie musisz tworzyć osobnych viewModeli. Dla tych PartialView modelem będą te kolekcje, które już masz.

0
michal84 napisał(a):

Wybacz, że namieszałem Tobie :).
Dla PartialView nie musisz tworzyć osobnych viewModeli. Dla tych PartialView modelem będą te kolekcje, które już masz.

Czyli wystarczy, że w partial view o nazwie np. _Details zrobie sobie @html.DisplayFor(cośtam) a potm wyrenderuję ten widok w Index
@html.Partial("/coś/coś/_Details.cshtml)?
Tylko co w przypadku jak PartialView to forma Create albo Edit? Wtedy nie da się tego wyrenderować tak:
@html.Partial("
/coś/coś/_Edit.cshtml)

1 użytkowników online, w tym zalogowanych: 0, gości: 1