web-dev-qa-db-ja.com

ASP.NET MVC 3-部分テンプレートvs表示テンプレートvsエディターテンプレート

だから、タイトルはそれ自体を語るべきです。

ASP.NET MVCで再利用可能なコンポーネントを作成するには、3つのオプションがあります(言及していない他のオプションもあります)。

部分図:

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

カスタムエディターテンプレート:

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

カスタム表示テンプレート:

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

実際のView/HTMLに関しては、3つの実装はすべて同一です。

@model WebApplications.Models.FooObject

<!-- Bunch of HTML -->

だから、私の質問は-いつ/どのように3つのうちどれを使用するかを決定しますか?

私が本当に探しているのは、質問を作成する前に自問する質問のリストです。その質問の答えを使用して、使用するテンプレートを決定できます。

EditorFor/DisplayForで見つけた2つのことは次のとおりです。

  1. HTMLヘルパーをレンダリングするときにモデル階層を尊重します(たとえば、「Foo」モデルに「Bar」オブジェクトがある場合、「Bar」のHTML要素は「Foo.Bar.ElementName」でレンダリングされますが、パーシャルは「 ElementName」)。

  2. より堅牢です。たとえば、ViewModelに何かのList<T>がある場合は、@Html.DisplayFor(model => model.CollectionOfFoo)を使用できます。MVCは、コレクションであることがわかり、各アイテムの単一の表示をレンダリングするのに十分です(パーシャルではなく、明示的なforループ)。

DisplayForが「読み取り専用」テンプレートをレンダリングすることも聞いたことがありますが、それを理解できません。フォームをそこに投げることはできませんか?

誰か他の理由を教えてもらえますか? 3つを比較するリスト/記事はどこかにありますか?

301
RPM1984

EditorFor vs DisplayForは簡単です。メソッドのセマンティクスは、編集/挿入ビューと表示/読み取り専用ビューをそれぞれ生成することです。データを表示するとき(つまり、モデル値を含むdivとspanを生成するとき)にDisplayForを使用します。データを編集/挿入するとき(つまり、フォーム内で入力タグを生成するとき)にEditorForを使用します。

上記のメソッドはモデル中心です。これは、モデルのメタデータを考慮に入れることを意味します(たとえば、モデルクラスに[UIHintAttribute]または[DisplayAttribute]の注釈を付けることができます。これは、モデルのUIを生成するために選択されるテンプレートに影響します。通常、データモデルにも使用されます。データベース内の行を表すモデルなど)

一方、Partialはビュー中心です。これは、正しい部分ビューの選択に最も関心があるという点です。ビューは、正しく機能するために必ずしもモデルを必要としません。サイト全体で再利用されるマークアップの共通セットを持つことができます。もちろん、このパーシャルの振る舞いに影響を与えたい場合がよくあります。その場合、適切なビューモデルを渡すことができます。

@Html.Actionについては質問しなかったので、ここでも言及する価値があります。コントローラーの子アクションを実行してからビュー(通常は部分ビュー)をレンダリングするという点で、Partialのより強力なバージョンと考えることができます。子アクションは、部分ビューに属さない追加のビジネスロジックを実行できるため、これは重要です。たとえば、ショッピングカートコンポーネントを表すことができます。これを使用する理由は、アプリケーション内のすべてのコントローラーでショッピングカート関連の作業を実行しないようにするためです。

最終的に、選択はアプリケーションでモデリングするものによって異なります。また、組み合わせて使用​​できることも忘れないでください。たとえば、EditorForヘルパーを呼び出す部分ビューを作成できます。それは本当にあなたのアプリケーションが何であるかと、繰り返しを避けながら最大限のコードの再利用を促進するためにそれをどのように因数分解するかに依存します。

297
marcind

確かにcould編集可能なフォームを表示するためにDisplayForをカスタマイズします。しかし、慣例では、DisplayForreadonlyに、EditorForを編集用にしています。慣習に従うことで、DisplayForに何を渡しても同じタイプのことを確実に行うことができます。

15
Robert Levy

私の2cの価値を与えるために、プロジェクトではいくつかのjQueryタブを持つ部分ビューを使用し、各タブは独自の部分ビューでフィールドをレンダリングします。これは、一部のタブがいくつかの共通フィールドを共有する機能を追加するまで正常に機能しました。これに対する最初のアプローチは、これらの共通フィールドを使用して別の部分ビューを作成することでしたが、EditorForとDropDownListForを使用してフィールドとドロップダウンをレンダリングすると非常に不格好になりました。一意のIDと名前を取得するために、フィールドをレンダリングしていた親の部分ビューに応じて、フィールドをプレフィックスでレンダリングする必要がありました。

    <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>

これはかなりいので、代わりにEditor Templatesを使用することにしました。共通フィールドを持つ新しいビューモデルを追加し、一致するエディターテンプレートを追加し、異なる親ビューからエディターテンプレートを使用してフィールドをレンダリングしました。 Editor Templateは、IDと名前を正しくレンダリングします。

要するに、エディターテンプレートを使用する説得力のある理由は、複数のタブでいくつかの共通フィールドをレンダリングする必要があるということです。部分ビューはこのために設計されていませんが、エディターテンプレートはシナリオを完全に処理します。

13
Ciaran Bruen

次の場合は、_partialビューアプローチを使用します。

  1. セントリックロジックを表示
  2. このビューでのみ_partialビューに関連するすべてのHTMLを保持するもの。テンプレートメソッドでは、「メインヘッダーまたは外側の境界線/設定」など、テンプレートビューの外側にHTMLを保持する必要があります。
  3. URL.Action("action","controller")を使用してロジック(コントローラーから)で部分ビューをレンダリングしたい。

テンプレートを使用する理由:

  1. ForEach(Iterator)を削除したい。テンプレートは、モデルをリストタイプとして識別するのに十分です。自動的に行われます。
  2. モデルセントリックロジック。テンプレートフォルダーの同じディスプレイで複数のビューが見つかった場合、レンダリングは渡されたモデルに依存します。
1
jitendra joshi

これまで言及されていない別の違いは、テンプレートが追加するのに対して、partialviewはモデルのプレフィックスを追加しないことです Here が問題です

1
erhan355