5

ビューモデルの階層を持つ複雑なフォームがあり、コントローラーにすべてのアクションのハンドラーが含まれないようにコードを構造化する方法を考えています。

簡単な例を次に示します: 複雑な ViewModel のサンプル ビュー 対応する ViewModel を使用:

public class MyPageViewModel
{
   public List<TabViewModel> Tabs {get; set; }
   public CustomerViewModel Customer;
}

public class TabViewModel
{
    public string DisplayLabel { get; set; }
    public bool Selected { get; set; }
}

class CustomerViewModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public List<Address> Addresses { get; set; }
}  

public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
}

ページの各部分のレンダリングを個別のコンポーネントに分割する方法を知っています。モデルの各部分に個別のビューを使用@Html.EditorFor@Html.DisplayForています (上の図の赤い四角形で示されています)。これは非常にうまく機能します。ViewModel の一部 (TabViewModelクラスなど) は、他のページでも再利用できます。

イベント処理ロジックに問題があります。このページで実行できるアクションはほとんどありません (青い背景で示されています)。1 つの可能性は、複数の FORM タグを使用することです。それぞれが上の図の 1 つの赤い四角形です。各フォームには異なるアクション URL があり、異なるコントローラーによって処理されます。しかし、このアプローチを使用すると、同じデータが失われる可能性があります。たとえば、ユーザーが First Name を変更してから [Remove Address] ボタンをクリックすると、First Name はサーバーに POST されず、変更は失われます。

これにより、ページ全体に対して 1 つのフォームが残ります。これは、すべてのアクションが単一のコントローラ クラスによって処理される必要があることを意味します。次の理由から、私はこのアプローチが本当に好きではありません。

  • すべてのボタンのアクション処理コードを含む大きくて太ったコントローラーになってしまいます
  • または、コントローラー内に大きな switch ステートメントを用意します。これは、アクションを識別し、アクションを処理する方法を知っている別のクラスを見つけ、それに処理を委譲します (うん! これは、Windows メッセージのイベント処理コードを1990年代 – WindowProc)

ビューから別のコントローラーを呼び出すことができる Html.ActionFor について読んだことがありますが、これも良いアプローチではないと思います (ビューがレンダリングされている間に発生しますが、これは問題ありません)。

要約すると、もう一度質問があります。複雑なビューモデルのさまざまな部分からトリガーされたアクション/イベントを、コントローラーで混乱しないように処理する方法はありますか? 実際のアプリケーションのベスト プラクティスは何ですか (Visual Studio のスキャフォールディングによって生成される 101 の CRUD の例ではありません)。

更新:これは単純化された例にすぎないことに注意してください。実際には、ビュー モデルははるかに複雑であり、実行できるアクションはさらに多くあります。ASP.NET MVC アプリケーションでコントローラー内のコードを構造化する (または別のクラスに移動する) ための一般的なアプローチについて質問しています。Web フォームはユーザー コントロールを提供し、ビュー パーツ (ASCX) とイベント ハンドラーの両方をカプセル化することができました。MVC にはビューをカプセル化するための優れたソリューションがあり、ロジック/イベント ハンドラーを構造化する正しい方法を見つけようとしています。

4

1 に答える 1

0

顧客データ フィールドセットの [保存] ボタンを追加し、ユーザーが [保存] ボタンを押したときにすべての顧客データを保存/投稿します。このように、Edit Post アクションでは のみを使用しますCustomerViewModel

「新しいアドレスを追加」と「このアドレスを削除」はAddress、javascript で必要な html を追加および削除します。

「既存の顧客を検索」および「外部DBから選択」は、フォーム内の敬意を表するセクションに必要なデータを含むポップアップを表示できます。Ajax を使用してデータを取得します。

このようにして、CustomerData フィールドセット用の単純な Edit Post アクション、ポップアップでデータを表示するための 2 つのアクション、およびアドレス セクションを操作するための JavaScript が用意されます。

于 2013-10-19T15:58:51.000 に答える