Załóżmy, że mam ViewModel jak
public class AnotherViewModel
{
public string Name { get; set; }
}
public class MyViewModel
{
public string Name { get; set; }
public AnotherViewModel Child { get; set; }
public AnotherViewModel Child2 { get; set; }
}
W widoku mogę renderować częściowe za pomocą
<% Html.RenderPartial("AnotherViewModelControl", Model.Child) %>
W części zrobię
<%= Html.TextBox("Name", Model.Name) %>
or
<%= Html.TextBoxFor(x => x.Name) %>
Jednak problem polega na tym, że oba będą renderować name = "Name", podczas gdy ja potrzebuję mieć name = "Child.Name", aby spinacz modelu działał poprawnie. Lub name = "Child2.Name", gdy renderuję drugą właściwość przy użyciu tego samego widoku częściowego.
Jak sprawić, by widok częściowy automatycznie rozpoznawał wymagany prefiks? Mogę podać to jako parametr, ale jest to zbyt niewygodne. Jest to jeszcze gorsze, gdy chcę, na przykład, renderować go rekurencyjnie. Czy istnieje sposób renderowania widoków częściowych z prefiksem, czy jeszcze lepiej, z automatyczną rekonstrukcją wywołującego wyrażenia lambda, tak aby
<% Html.RenderPartial("AnotherViewModelControl", Model.Child) %>
automatycznie doda poprawne „Dziecko”. prefiks do wygenerowanych ciągów nazwy / identyfikatora?
Mogę zaakceptować dowolne rozwiązanie, w tym zewnętrzne silniki i biblioteki widoku - faktycznie używam Spark View Engine („rozwiązuję” problem za pomocą jego makr) i MvcContrib, ale nie znalazłem tam rozwiązania. XForms, InputBuilder, MVC v2 - każde narzędzie / insight zapewniające tę funkcjonalność będzie świetne.
Obecnie sam myślę o zakodowaniu tego kodu, ale wydaje mi się, że to strata czasu, nie mogę uwierzyć, że ta trywialna rzecz nie jest już zaimplementowana.
Może istnieć wiele rozwiązań ręcznych i wszystkie z nich są mile widziane. Na przykład mogę zmusić moje części składowe, aby były oparte na IPartialViewModel <T> {public string Prefix; Model T; }. Ale wolałbym jakieś istniejące / zatwierdzone rozwiązanie.
UPDATE: tam podobne pytanie bez odpowiedzi tutaj .
źródło
helper.ViewData.TemplateInfo.HtmlFieldPrefix
w postaci{oldprefix}.{newprefix}
new ViewDataDictionary(helper.ViewData)
sięnew ViewDataDictionary(((HtmlHelper)helper).ViewData)
. Czy widzisz z tym jakiś problem?string oldPrefix = helper.ViewData.TemplateInfo.HtmlFieldPrefix; if (oldPrefix != "") name = oldPrefix + "." + name;
do tej pory szukałem tego samego, co znalazłem w ostatnim wpisie:
http://davybrion.com/blog/2011/01/prefixing-input-elements-of-partial-views-with-asp-net-mvc/
źródło
ViewDataDictionary
konstruktora, który pobiera prądViewData
, albo stracisz błędy stanu modelu, dane walidacyjne itp.Moja odpowiedź na podstawie odpowiedzi Mahmouda Moraveja, w tym komentarza Ivana Zlateva.
Edycja: odpowiedź Mohamoud jest niepoprawna dla zagnieżdżonego renderowania częściowego. Musisz dodać nowy prefiks do starego przedrostka, tylko jeśli jest to konieczne. Nie było to jasne w ostatnich odpowiedziach (:
źródło
Dzięki MVC2 możesz to osiągnąć.
Oto widok silnie wpisany:
Oto widok silnie wpisany dla klasy podrzędnej (który musi być przechowywany w podfolderze katalogu widoku o nazwie EditorTemplates):
Oto kontroler:
Oto klasy niestandardowe:
I źródło wyjściowe:
Teraz to jest zakończone. Ustaw punkt przerwania w akcji kontrolera Utwórz post do weryfikacji. Nie używaj tego jednak z listami, ponieważ to nie zadziała. Zobacz moje pytanie dotyczące używania EditorTemplates z IEnumerable, aby uzyskać więcej informacji na ten temat.
źródło
Html.EditorFor
metody renderowania formularza podrzędnego. Właśnie do tego mają służyć szablony edytorów. To powinna być odpowiedź.To stare pytanie, ale dla każdego, kto przyjeżdża tutaj i szuka rozwiązania, rozważ użycie
EditorFor
, jak zasugerowano w komentarzu na https://stackoverflow.com/a/29809907/456456 . Aby przejść z częściowego widoku do szablonu edytora, wykonaj następujące kroki.Sprawdź, czy widok częściowy jest powiązany z typem ComplexType .
Przenieś widok częściowy do podfolderu EditorTemplates w bieżącym folderze widoku lub do folderu Shared . Teraz jest to szablon edytora.
Zmień
@Html.Partial("_PartialViewName", Model.ComplexType)
na@Html.EditorFor(m => m.ComplexType, "_EditorTemplateName")
. Szablon edytora jest opcjonalny, jeśli jest to jedyny szablon dla typu złożonego.Elementy wejściowe HTML zostaną automatycznie nazwane
ComplexType.Fieldname
.źródło
PartailFor dla asp.net Core 2 na wypadek, gdyby ktoś tego potrzebował.
źródło
Natknąłem się również na ten problem i po wielu bólach stwierdziłem, że łatwiej było przeprojektować moje interfejsy tak, że nie musiałem ponownie publikować zagnieżdżonych obiektów modelu. Zmusiło mnie to do zmiany przepływów pracy w interfejsie: z pewnością wymagam teraz od użytkownika wykonania w dwóch krokach tego, o czym marzyłem, na jednym, ale użyteczność i łatwość utrzymania kodu nowego podejścia ma teraz dla mnie większą wartość.
Mam nadzieję, że to pomoże niektórym.
źródło
Możesz dodać pomocnika dla RenderPartial, który pobiera prefiks i wstawia go do ViewData.
Następnie kolejny pomocnik, który konkatenuje wartość ViewData
i tak na widoku ...
w częściowym ...
źródło
Podobnie jak Ty, dodaję właściwość Prefix (ciąg) do moich ViewModels, które dołączam przed nazwami wejściowymi powiązanymi z modelem. (YAGNI zapobiega poniższym)
Bardziej eleganckim rozwiązaniem może być model widoku podstawowego, który ma tę właściwość i niektóre HtmlHelpers, które sprawdzają, czy model widoku pochodzi z tej bazy, a jeśli tak, dołącz prefiks do nazwy wejściowej.
Mam nadzieję, że to pomoże
Dan
źródło
Może tuż przed wywołaniem RenderPartial
Więc w swojej części masz
źródło