9

ASP.NET MVCの「RenderPartial()」メソッドは、非常に低レベルの機能を提供します。真の「サブコントローラー」モデルを提供したり、提供しようとしたりすることはありません*。

'RenderPartial()'を介してレンダリングされるコントロールの数が増えています。それらは3つの主要なカテゴリに分類されます。

1)そのページのモデルを使用する特定のページの直接の子孫であるコントロール

2)特定のページの直接の子孫であり、そのページのモデルを特定の タイプの追加のキーとともに使用するコントロール。'DataRepeater'の実装を考えてください。

3)表示されるページに関連のない機能を表すコントロール。これは、バナーローテーターから、フィードバックフォーム、ストアロケーター、メーリングリストのサインアップまで、何でもかまいません。重要なのは、どのページに配置されているかは関係ないということです。

モデルの動作方法により、ViewDataリクエストごとに1つのモデルオブジェクトしか存在しません。つまり、サブコントロールに必要なものはすべてページモデルに存在する必要があります。

最終的に、MVCチームは真の「サブコントローラー」モデルを作成することを望んでいますが、それまでは、子コントロールにも必要なものをメインページモデルに追加するだけです。

上記の(3)の場合、これは「ProductModel」のモデルに「MailingListSignup」モデルのフィールドが含まれている必要がある可能性があることを意味します。明らかにそれは理想的ではありませんが、私はこれを現在のフレームワークとの最良の妥協点で受け入れました-そして将来のサブコントローラーモデルへの「ドアを閉める」可能性は最も低いです。

モデルは実際にはデータをどこから取得するかを知らないダムデータ構造である必要があるため、コントローラーはモデルのデータを取得する責任を負う必要があります。しかし、コントローラーがいくつかの異なる場所でモデルを作成する必要はありません。

私が始めたのは、モデルを作成するためのファクトリを作成することです。このファクトリはコントローラによって呼び出されます(モデルはファクトリについて認識していません)。

public static class JoinMailingListModelFactory {

        public static JoinMailingListModel CreateJoinMailingListModel() {

            return new JoinMailingListModel()
            {
                MailingLists = MailingListCache.GetPartnerMailingLists();
            };
        }
    }   

ですから、私の実際の質問は、この同じ問題を抱えている他の人々が実際にモデルをどのように作成しているかということです。新しいMVC機能との将来の互換性のための最良のアプローチは何でしょうか?


  • 注意:ここでは取り上げRenderAction()ない問題があります。特に、MVCContribのみであり、ASP.NET-MVCのRTMバージョンには含まれないという問題があります。他の問題は私がそれを使わないことを選んだ十分な問題を引き起こしました。それで、今のところRenderPartial()存在するだけのふりをしましょう-または少なくともそれは私が使用することに決めたものです。
4

4 に答える 4

5

MailingListSignupのプロパティとしてのようなものを追加する代わりに、次のようなProductModelクラスの同じレベルで両方をカプセル化します。ProductViewModel

public class ProductViewModel() {
    public ProductModel productModel;
    public MailingListSignup signup;
}

次に、ビューをクラスに強く型付けしProductViewModelます。ProductModelを呼び出して にアクセスできModel.productModel、 を使用してサインアップ クラスにアクセスできますModel.signup

これは、Fowler の「プレゼンテーション モデル」( http://martinfowler.com/eaaDev/PresentationModel.html ) の大まかな解釈ですが、Rob Conery や Stephen Walther などの Microsoft 開発者によって使用されているのを見てきました。

于 2009-03-16T05:47:49.847 に答える
2

このシナリオで私が見たアプローチの 1 つは、アクション フィルターを使用して、部分ビュー (サブクラス) のデータを入力することActionFilterAttributeです。でOnActionExecuting、データを ViewData に追加します。次に、その部分ビューを使用するさまざまなアクションをフィルターで装飾するだけです。

于 2009-03-13T05:58:23.377 に答える
1

私が使用する RenderPartial オーバーロードがあり、新しい ViewData と Model を指定できます。

RenderPartial コード

MVC ソース コードの前のリンクと次を参照すると (RenderPartialInternal メソッドを探します)。

RenderPartial内部コード

基本的にビューデータをコピーすると、渡した新しいディクショナリを作成し、モデルをコントロールで使用するように設定することがわかります。そのため、ページはモデルを持つことができますが、別のモデルをサブコントロールに渡します。

サブコントロールがメイン ビュー モデルから直接参照されていない場合は、Marc Gravell が言及しているトリックを実行して、カスタム ロジックを追加できます。

于 2009-03-13T20:19:13.120 に答える
0

私が試した方法の 1 つは、インターフェイスで厳密に型指定された部分ビューを使用することでした。ほとんどの場合、集約された ViewModel の方が優れた方法ですが、それでも共有したいと思います。

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IMailingListSignup>" %>

Viewmodel はインターフェイスを実装します

 public class ProductViewModel:IMailingListSignup

これは完全ではありませんが、いくつかの問題を解決します。ルートからモデルにプロパティを簡単にマッピングできます。それ以外の場合、ルートパラメーターを MailingListSignup のプロパティにマップできるかどうかはわかりません。

モデルを埋めるという問題がまだあります。遅くない場合は、OnActionExecuted で実行することをお勧めします。OnActionExecuting でモデルを埋める方法がわかりません。

于 2009-07-07T21:34:41.967 に答える