2010-02-08 15 views
5

Zastanawiam się, gdzie ludzie tworzą swoją listę wyboru - w akcji lub widoku.ASP.net MVC: Tworzenie SelectList w widoku lub akcji?

Widziałem przykłady zarówno tych, jak i tych, które są dla mnie najbardziej sensowne, ponieważ robią to w akcji i mają model widoku ma właściwość typu SelectList.

Z drugiej strony widziałem przykłady, w których ludzie mają model widoku mają właściwość SelectList, a SelectList jest wypełniany w modelu widoku (w konstruktorze lub poprzez leniwy ładowanie). Podoba mi się ten pomysł, ponieważ oznacza to, że w moich działaniach jest mniej kodu ...

Krótko mówiąc, zastanawiałem się, co robią ludzie.

Cheers Anthony

Odpowiedz

5

Utwórz SelectList w kontrolerze (przez patrząc listę elementów z repozytorium modelu) i przekazać je do widoku zarówno jako obiekt ViewData lub jako część silnie wpisany ViewModel.

+0

Dlaczego? Byłbym szczęśliwy, gdyby udało się przedstawić bardziej szczegółowe informacje na temat tego, dlaczego uważasz, że to podejście jest lepsze. Czy łatwiej jest testować? Promować ponowne wykorzystanie kodu? Lepsze oddzielenie obaw? –

+0

@Seth: Celem mocno napisanego obiektu ViewModel jest spakowanie wszystkich danych wymaganych przez widok, aby renderować go poprawnie. W takim przypadku, ponieważ lista rozwijana wymaga listy elementów, należy ją uwzględnić w obiekcie ViewModel. Programista, który będzie podążał za mną, zobaczy Listę SelectList w ViewModel i wywnioskuje, że jest używana do zapełnienia listy w widoku. I nie musi szukać nigdzie indziej. –

+0

@Robert: Całkowicie się z tobą zgadzam.Chodzi mi o to, że twoja odpowiedź została wybrana jako "poprawna" i pomyślałem, że dodatkowe informacje mogą okazać się pomocne dla kogoś, kto napotka to pytanie w przyszłości. Wolałbym nowych programistów MVC wiedzieć, dlaczego to jest lepsze, zamiast ślepo podążać za odpowiedzią SO :) –

1

Zazwyczaj tworzę moją listę SelectList w warstwie akcji lub usługi i przekazuję ją do mojego widoku poprzez ViewData. Stworzyłem także część modelu widoku i mocno napisany widok. Oba sposoby tworzą go jednak w warstwie akcji lub usługi.

+0

Przekazywanie SelectLists przez ViewData jest OK, ale jeśli twoja strona jest silnie wpisana do obiektu ViewModel, to czystsze jest tylko włączenie twoich SelectLists jako część ViewModel: –

+0

zgodził się, i to jest to, co robię, jeśli trzeba wysłać więcej danych do widoku niż tylko listę wyboru.Jeśli wszystko, czego potrzebuję jest listą wyboru, to zwykle używam ViewDat za. –

1

Mam SelectList narażone jako właściwość w modelu widoku i wypełnić go w akcji przy użyciu niezbędnego repozytorium. Myślę, że kod, który współdziała bezpośrednio z repozytoriami, powinien być odpowiedzialny za wypełnianie, czy to działania kontrolera, czy warstwę usługi, czy cokolwiek innego.

Nie sądzę, że zapełnianie listy bezpośrednio z modelu widoku jest dobrym pomysłem, ponieważ wymagałoby modelu widoku, aby mieć zależność od repozytorium i interakcji z bazą danych, a model widoku nie powinien być odpowiedzialny za tego rodzaju od rzeczy.

Można również utworzyć oddzielny obiekt specjalny o nazwie Initializer lub coś podobnego, który wykonuje wszystkie zaludnienia i inicjalizacje, jeśli masz kilka pól SelectList i chcesz zachować czystość kodu akcji.

+0

"Nie sądzę, że zapełnianie listy bezpośrednio z modelu widoku jest dobrym pomysłem, ponieważ wymagałoby modelu widoku, aby mieć zależność od repozytorium" - Niekoniecznie. Model widoku jest zapełniony w kontrolerze (w tym lista elementów wymaganych dla SelectList), więc nie jest wymagana zależność od repozytorium w samym modelu widoku. –

+0

To była dokładnie moja uwaga. Kod wypełniający repozytorium powinien zostać wywołany ze sterownika, a nie z wewnątrz kodu modelu widoku (konstruktora lub innej metody). – Victor

2

Jest to aspekt specyficzny dla prezentacji, więc wolę zrobić to w widoku przy użyciu helpera HTML. Tak więc przekazuję kolekcję do widoku i używam metody helpera html do mapowania elementów do SelectListItems. Metoda może wyglądać bardzo podobnie:

public static IList<SelectListItem> MapToSelectItems<T>(this IEnumerable<T> itemsToMap, Func<T, string> textProperty, Func<T, string> valueProperty, Predicate<T> isSelected) 
{ 
    var result = new List<SelectListItem>(); 

    foreach (var item in itemsToMap) 
    { 
     result.Add(new SelectListItem 
     { 
      Value = valueProperty(item), 
      Text = textProperty(item), 
      Selected = isSelected(item) 
     }); 
    } 
    return result; 
} 

Pozdrawiam.

+0

Nadal musisz utworzyć listę elementów w swoim ViewModelu, więc dlaczego nie po prostu zrobić to SelectList? –

+0

Masz rację, ja myślałem o modelu tak samo jak encja lub dto tłumaczone z bytu (nie jako model specyficzny dla widoku lub ViewModel), w każdym razie możesz użyć powyższej metody do tłumaczenia. – uvita

+0

Uważam, że modele z widokiem powinny prawdopodobnie bezpośrednio eksponować listę SelectList, ponieważ zmniejsza ona ilość kodu, który trzeba napisać w widoku, nawet jeśli tylko trochę. Ale w niektórych przypadkach przekazuję DTO lub obiekt biznesowy do widoku, aw takich przypadkach wezwę pomocnika takiego jak ty powyżej (moja nazwa nazywa się .ToSelectList()]. Myślę, że oba podejścia są odpowiednie w różnych scenariuszach. –

Powiązane problemy