2011-06-27 10 views
6

Używam maszynki do golenia MVC3. Mam scenariusz, w którym muszę wielokrotnie używać widoku częściowego w tym samym widoku nadrzędnym. Problem polega na tym, że gdy widok nadrzędny jest renderowany, generuje te same nazwy i identyfikatory kontrolek wejściowych w tych widokach częściowych. Ponieważ moje widoki częściowe są powiązane z różnymi modelami, gdy widok jest ponownie wysłany na "Zapisz", ulega awarii. Każdy pomysł, w jaki sposób mogę uczynić identyfikator kontrolny/nazwy unikalne, prawdopodobnie niektóre jak przedrostek je?Używanie jednego widoku częściowego Wielokrotnie w tym samym widoku nadrzędnym

Czekamy

Nabeel

Odpowiedz

5

osobiście wolę przy użyciu szablonów redaktor, jak dbać o tym. Na przykład można mieć następujący model wyświetlania:

public class MyViewModel 
{ 
    public ChildViewModel Child1 { get; set; } 
    public ChildViewModel Child2 { get; set; } 
} 

public class ChildViewModel 
{ 
    public string Foo { get; set; } 
} 

i następujący Kontroler:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     var model = new MyViewModel 
     { 
      Child1 = new ChildViewModel(), 
      Child2 = new ChildViewModel(), 
     }; 
     return View(model); 
    } 

    [HttpPost] 
    public ActionResult Index(MyViewModel model) 
    { 
     return View(model); 
    } 
} 

i wewnątrz Index.cshtml widzenia:

@model MyViewModel 
@using (Html.BeginForm()) 
{ 
    <h3>Child1</h3> 
    @Html.EditorFor(x => x.Child1) 

    <h3>Child2</h3> 
    @Html.EditorFor(x => x.Child2) 
    <input type="submit" value="OK" /> 
} 

i ostatnia część jest szablon redaktor (~/Views/Home/EditorTemplates/ChildViewModel.cshtml):

@model ChildViewModel 

@Html.LabelFor(x => x.Foo) 
@Html.EditorFor(x => x.Foo) 

Można użyć szablonu dla różnych właściwości głównego modelu widoku, a poprawne nazwy/identyfikatory będą generowane. Oprócz tego model podglądu zostanie poprawnie wypełniony w akcji POST.

2
Nie

jest alternatywą:

  1. Dodaj prefiks do PartialView
  2. Bind modelu, usuwając prefiks

za 1, ustawić prefiks w widoku:

ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = "prefix"; 

Dla 2 można odzyskać dane za pomocą UpdateModel, podobnie jak poniżej:

UpdateModel(producto, "prefix"); 

Nie jest to zalecane, ponieważ Twoje działanie nie przyjmuje danych jako parametru, ale później aktualizuje model. Ma to kilka niedogodności: 1) nie jest jasne, jakie są twoje potrzeby w działaniu, patrząc na jego sygnaturę 2) nie jest łatwo podać dane wejściowe do akcji dla testowania jednostki 3) działanie jest podatne na parametry przepełnienia (parametry dostarczone przez użytkownika nie powinno tam być i są mapowane do modelu).

Jednak dla 2 istnieje alternatywa: zarejestruj niestandardowy segregator modelu, który umożliwia usunięcie prefiksu. A niestandardowy Model Binder musi o tym wiedzieć.

Dobrym rozwiązaniem jest w tym SO Q & A: How to handle MVC model binding prefix with same form repeated for each row of a collection? Ale ma trochę wadę: jeśli dodać ukryte pole z nazwą „__prefix” w częściowym widokiem, i uczynić go kilka razy częściowym widokiem Ten identyfikator będzie powtarzany dla kilku różnych elementów na stronie, co jest niedozwolone i może spowodować pewne problemy. I jedną z najważniejszych przyczyn zapewnienia przedrostka jest właśnie renderowanie tego samego widoku "edycji", co widoków częściowych dla kilku instancji jednostki. To znaczy.stanie się tak na stronie takiej jak Gmail, w której możesz edytować kilka e-maili naraz.

Istnieje kilka możliwych rozwiązań tego problemu.

Jednym z nich jest przedrostek jako ciąg zapytania lub wartość routedata, a nie jako pole formularza, które pozwala uniknąć konfliktów identyfikatorów i które można znaleźć w segregatorze modelu. (Może zawsze mieć tę samą nazwę).

Innym rozwiązaniem jest użycie ukrytego pola o stałym wzorze, ale które jest inne dla każdego renderowanego widoku. Prefiks może być zgodny z tym wzorcem pod względem unikalności: "PP $ ActionControllerId" jak "PP $ EditProduct23", który jest unikalny dla każdego renderowanego widoku i można go łatwo znaleźć między parametrami żądania, szukającymi jednego rozpoczynającego się od "PP $".

Ostatecznym rozwiązaniem byłoby utworzenie przedrostka tylko w widoku i nie podanie go w żadnym parametrze żądania. Segregator modelu musiałby szukać prefiksu badającego nazwy parametrów żądania, dopóki nie znajdzie takiego, którego prefiks będzie zgodny z wzorcem.

Oczywiście niestandardowy modelBinder musi zostać dostosowany do pracy, aby wybrać wybraną konwencję.

Powiązane problemy