ASP.NET MVC 3-Partial vs Display Template vs Editor Template

Więc tytuł powinien mówić sam za siebie.

Do tworzenia elementów wielokrotnego użytku w ASP.NET MVC, mamy 3 opcje (mogą być inne, o których nie wspomniałem):

Widok Częściowy:

@Html.Partial(Model.Foo, "SomePartial")

Custom Editor Template:

@Html.EditorFor(model => model.Foo)

Niestandardowy Szablon Wyświetlania:

@Html.DisplayFor(model => model.Foo)

Jeśli chodzi o rzeczywisty widok / HTML, wszystkie trzy implementacje są identyczne:

@model WebApplications.Models.FooObject

<!-- Bunch of HTML -->

Więc moje pytanie brzmi-kiedy / jak zdecydować, który z trzech do użyć?

Tak naprawdę Szukam listy pytań, które należy zadać sobie przed utworzeniem, na które odpowiedzi można wykorzystać, aby zdecydować, którego szablonu użyć.

Oto 2 rzeczy, które znalazłem lepiej z EditorFor / DisplayFor:

  1. Respektują hierarchie modeli podczas renderowania helperów HTML (np. jeśli masz obiekt "Bar" w swoim modelu "Foo", elementy HTML dla "Bar" będą renderowane za pomocą " Foo.Bar.ElementName", podczas gdy częściowy będzie miał "ElementName").

  2. Jeśli masz List<T> czegoś w swoim Viewmodelu, możesz użyć @Html.DisplayFor(model => model.CollectionOfFoo), A MVC jest wystarczająco inteligentny, aby zobaczyć, że jest to kolekcja i wyrenderować Pojedynczy Wyświetlacz dla każdego elementu (w przeciwieństwie do częściowego, który wymagałby jawnej pętli for).

Słyszałem też, że DisplayFor renderuje szablon "tylko do odczytu", ale nie rozumiem tego - czy nie mógłbym wrzucić tam formularza?

Czy ktoś może mi powiedzieć jakieś inne powody? Czy jest lista / artykuł gdzieś porównujący te trzy?
Author: rene, 2011-02-18

5 answers

EditorFor vs {[1] } jest proste. Semantyką metod jest generowanie widoków edycji / Wstaw oraz wyświetlania / tylko do odczytu (odpowiednio). Użyj DisplayFor Podczas wyświetlania danych (np. podczas generowania Div I span zawierających wartości modelu). Użyj EditorFor podczas edycji / wstawiania danych(np. podczas generowania znaczników wejściowych wewnątrz formularza).

Powyższe metody są zorientowane na model. Oznacza to, że będą brać pod uwagę metadane modelu (na przykład możesz dodać adnotację do klasy modelu za pomocą [UIHintAttribute] lub [DisplayAttribute] i to miałoby wpływ na to, który szablon zostanie wybrany do generowania interfejsu użytkownika dla modelu. Są one również zwykle używane do modeli danych (tj. modeli, które reprezentują wiersze w bazie danych, itp.)

Z drugiej strony Partial jest zorientowany na widok, ponieważ chodzi głównie o wybór właściwego widoku częściowego. Widok niekoniecznie potrzebuje modelu do poprawnego działania. Może po prostu mieć wspólny zestaw znaczników, który jest ponownie używany w całej witrynie. Oczywiście często razy chcesz wpływa na zachowanie tego częściowego elementu, w którym to przypadku możesz chcieć przekazać odpowiedni model widoku.

Nie pytałeś o @Html.Action, co również zasługuje na wzmiankę tutaj. Można by pomyśleć o niej jako o potężniejszej wersji Partial, ponieważ wykonuje ona akcję potomną kontrolera, a następnie renderuje widok (który zazwyczaj jest częściowym widokiem). Jest to ważne, ponieważ akcja potomna może wykonać dodatkową logikę biznesową, która nie należy do częściowego widoku. Na przykład może reprezentować komponent koszyka. Powodem jej użycia jest uniknięcie wykonywania pracy związanej z koszykiem w każdym kontrolerze w Twojej aplikacji.

Ostatecznie wybór zależy od tego, co modelujesz w swojej aplikacji. Pamiętaj również, że możesz mieszać i dopasowywać. Na przykład możesz mieć widok częściowy, który wywołuje helper EditorFor. To naprawdę zależy od tego, jaka jest Twoja aplikacja i jak ją uwzględnić, aby zachęcić do maksymalnego ponownego użycia kodu, unikając powtórzeń.

 291
Author: marcind,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-25 08:39:24

Z pewnością mógłbyś dostosować DisplayFor, aby wyświetlić edytowalny formularz. Ale konwencja jest dla DisplayFor być readonly i EditorFor być dla edycji. Trzymanie się konwencji zapewni, że bez względu na to, co przejdziesz do DisplayFor, zrobi to samo.

 14
Author: Robert Levy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-16 07:54:42

Aby dać mi wartość 2c, nasz projekt używa częściowego widoku z kilkoma zakładkami jQuery, a każda zakładka renderuje swoje pola z własnym częściowym widokiem. Działało to dobrze, dopóki nie dodaliśmy funkcji, dzięki której niektóre karty dzieliły wspólne pola. Naszym pierwszym podejściem było utworzenie kolejnego częściowego widoku z tymi wspólnymi polami, ale stało się to bardzo niezgrabne, gdy używaliśmy EditorFor i DropDownListFor do renderowania pól i spadów. W celu uzyskania unikalnych identyfikatorów i nazw musieliśmy renderować pola z przedrostkiem zależnym od częściowego widoku nadrzędnego, który go renderował:

    <div id="div-@(idPrefix)2" class="toHide-@(idPrefix)" style="display:none">
    <fieldset>
        <label for="@(idPrefix).Frequency">Frequency<span style="color: #660000;"> *</span></label>

        <input name="@(idPrefix).Frequency"
               id="@(idPrefix)_Frequency"
               style="width: 50%;"
               type="text"
               value="@(defaultTimePoint.Frequency)"
               data-bind="value: viewState.@(viewStatePrefix).RecurringTimepoints.Frequency"
               data-val="true"
               data-val-required="The Frequency field is required."
               data-val-number="The field Frequency must be a number."
               data-val-range-min="1"
               data-val-range-max="24"
               data-val-range="The field Frequency must be between 1 and 24."
               data-val-ignore="true"/>

        @Html.ValidationMessage(idPrefix + ".Frequency")

        ... etc

    </fieldset>
</div>

Zrobiło się dość brzydko, więc zdecydowaliśmy się użyć szablonów edytorów, które wyszły znacznie czystsze. Dodaliśmy nowy Model widoku z polami wspólnymi, dodaliśmy pasujący szablon Edytora i wyrenderowaliśmy pola przy użyciu szablonu edytora z różnych widoków nadrzędnych. Szablon edytora poprawnie wyświetla identyfikatory i nazwy.

Krótko mówiąc, ważnym powodem, dla którego korzystaliśmy z szablonów edytorów, było potrzeba renderowania niektórych wspólnych pól w wielu kartach. Widoki częściowe nie są do tego przeznaczone, ale Szablony edytorów doskonale obsługują scenariusz.

 13
Author: Ciaran Bruen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-21 21:00:52

Użyj podejścia _partial, Jeśli:

  1. Widok Logiki Centrycznej
  2. co zachować wszystkie {[0] } widok powiązany HTML tylko w tym widoku. W metodzie szablonu będziesz musiał zachować część HTML poza widokiem szablonu, np. " nagłówek główny lub dowolna zewnętrzna ramka / ustawienia.
  3. chce renderować częściowy widok za pomocą logiki (z kontrolera) przy użyciu URL.Action("action","controller").

Powody użycia szablonu:

  1. Chcę usunąć ForEach(Iterator). Szablon jest wystarczająco dobry, aby zidentyfikować Model jako typ listy. Będzie zrób to automatycznie.
  2. Modelowa Logika Centryczna. Jeśli w tym samym folderze Displayfor znajduje się wiele widoków, renderowanie będzie zależeć od przekazanego modelu.
 1
Author: jitendra joshi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-31 21:23:59

Kolejną różnicą, o której nie wspomniano do tej pory, jest to, że widok częściowy nie dodaje prefiksów modelu, podczas gdy szablon Tutaj jest problem

 1
Author: erhan355,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-14 13:20:18