306

したがって、タイトルはそれ自体で語るべきです。

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. より堅牢です。たとえばList<T>、ViewModel に何かがある場合は、 を使用できます。MVC は、@Html.DisplayFor(model => model.CollectionOfFoo)それがコレクションであることを認識し、各アイテムの単一の表示をレンダリングするのに十分スマートです (パーシャルでは、明示的な for が必要になるのとは対照的に)。ループ)。

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

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

4

5 に答える 5

304

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

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

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

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

最終的には、アプリケーションで何をモデル化するかによって選択が異なります。また、組み合わせて使用​​できることも忘れないでください。たとえば、EditorForヘルパーを呼び出す部分的なビューを持つことができます。それは、アプリケーションが何であるか、および反復を避けながらコードの再利用を最大限に促進するためにそれをどのように考慮に入れるかによって大きく異なります。

于 2011-02-18T04:30:43.340 に答える
15

確かに、編集可能なフォームを表示するようにカスタマイズできます。DisplayForしかし、慣習は編集のためのDisplayForものでreadonlyありEditorFor、編集のためのものです。慣習に従うことで、 に何を渡してDisplayForも、同じタイプのことを行うことが保証されます。

于 2011-02-18T04:31:06.853 に答える
13

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

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

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

于 2012-02-20T21:18:21.620 に答える
1

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

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

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

  1. 削除したいForEach(Iterator)。テンプレートは、モデルをリスト型として識別するのに十分です。それは自動的にそれを行います。
  2. モデル中心のロジック。テンプレート フォルダの同じ表示に複数のビューが見つかった場合、レンダリングは渡されたモデルに依存します。
于 2015-10-05T07:27:00.240 に答える
1

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

于 2017-06-14T12:22:02.680 に答える