3

部分ビューの使用方法を理解しています。また、ビューでそれらを設定する方法については、Ajax.ActionLink と Ajax.BeginForm を理解しています。各部分ビューには独自のコントローラーがあると想定しています。ここでは、境界付けられたコンテキストを考えています。各部分ビューでは、独自のコントローラーを介して独自の境界付けられたコンテキストと通信できるためです。

私が見逃している作品は次のとおりです。

  1. 部分ビューを「マスター ビュー」(または保持ビュー) に含め、これらの各部分ビューを別々のコントローラー アクションに個別に投稿し、「マスター ビュー」または保持ビューをロードせずに部分ビューを更新する方法.
  2. 「マスター」ビューまたは保持ビューには独自のコントローラーが必要です。マスターコントローラーがビューをリロードしないようにし、マスターコントローラーのアクションメソッドによって生成されたビューにこれら2つの部分への参照を保持させたいビュー。

考えられるアプローチは 2 つあります。1 つは「Ajax」を使用することです。もう 1 つは、ストレートな jQuery を使用して、クライアント側からこのすべてのやり取りを手動で処理することです。

私がやろうとしていることは両方の方法で可能ですか、それともこのタイプの複合UI構築に「より適した」方法ですか?

これまでのところ、私が見た唯一のものは、ページ上のシングルを更新する Ajax.ActionLink を介したリンクや、div を a部分的なビュー。

4

1 に答える 1

4

よし、ようやく正しい方法だと思われる実用的なコードがいくつかできました。これが私が行ったものです。2 つの単純な「エンティティ」があります。顧客と BillingCustomer。それらは実際には別々の「境界付けられたコンテキスト」にあることを意図しており、クラスはデモストレーションの目的のために非常に単純です。

public class Customer
{ 
    public Guid CustomerId { get; set; }
    public string Name { get; set; }
}

public class BillingCustomer
{
    public Guid CustomerId { get; set; }
    public bool IsOverdueForPayment { get; set; }
}

両方のクラスが CustomerId を参照していることに注意してください。このデモでは、これは GUID です。

まず、Index.cshtml ファイルで使用される ViewModel を構築する単純な HomeController から始めました。

public ActionResult Index()
{
    var customer = new Customer {
        CustomerId = Guid.Empty, 
        Name = "Mike McCarthy" };

    var billingCustomer = new BillingCustomer { 
        CustomerId = Guid.Empty, 
        IsOverdueForPayment = true };

    var compositeViewModel = new CompositeViewModel {
        Customer = customer, 
        BillingCustomer = billingCustomer };

    return View(compositeViewModel);
}

CompositeViewModel クラスは、各ドメイン エンティティのプロパティを持つ単なる DTO です。これは、Index.cshtml ファイルで呼び出す部分ビューが、それぞれのドメイン モデルを部分ビューに渡す必要があるためです。

public class CompositeViewModel
{
    public BillingCustomer BillingCustomer { get; set; }
    public Customer Customer { get; set; }
}

HomeController で Index メソッドを使用する結果の Index.cshtml ファイルを次に示します。

@model CompositeViews.ViewModels.CompositeViewModel

<h2>Index - @DateTime.Now.ToString()</h2>

<div id="customerDiv">
    @{Html.RenderPartial("_Customer", Model.Customer);}
</div>

<p></p>

<div id="billingCustomerDiv">
    @Html.Partial("_BillingCustomer", Model.BillingCustomer)
</div>

ここで注意すべき点がいくつかあります。

  1. ビューは CompositeViews.ViewModels.CompositeViewModel ViewModel を使用しています
  2. Html.RenderPartial は、各エンティティの部分ビューをレンダリングするために使用され、適切なエンティティを渡します。Html.Partial 呼び出しの構文に注意してください。

したがって、ここに _Customer 部分ビューがあります。

@model CompositeViews.Models.Customer

@using (Ajax.BeginForm("Edit", "Customer", new AjaxOptions { 
    HttpMethod = "POST", 
    InsertionMode = InsertionMode.Replace, 
    UpdateTargetId = "customerDiv" }))
{
    <fieldset>
        <legend>Customer</legend>

        @Html.HiddenFor(model => model.CustomerId)

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>

        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}

ここで重要な部分は、Ajax.BeginForm 呼び出しです。CustomerController の Edit ActionMethod を明示的に呼び出していることに注意してください。また、UpdateTargetId が「customerDiv」に設定されていることにも注意してください。この div は部分ビューではなく、"親" ビューの Index.cshtml にあります。

以下は _BillingCustomer ビューです

@model CompositeViews.Models.BillingCustomer

@using (Ajax.BeginForm("Edit", "BillingCustomer", new AjaxOptions { 
    HttpMethod = "POST", 
    InsertionMode = InsertionMode.Replace, 
    UpdateTargetId = "billingCustomerDiv" }))
{
<fieldset>
    <legend>BillingCustomer</legend>

    @Html.HiddenFor(model => model.CustomerId)

    <div class="editor-label">
        @Html.LabelFor(model => model.IsOverdueForPayment)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.IsOverdueForPayment)
        @Html.ValidationMessageFor(model => model.IsOverdueForPayment)
    </div>

    <p>
        <input type="submit" value="Save" />
    </p>
</fieldset>
}

ここでも、UpdateTargetId がbillingCustomerDiv に設定されていることに注意してください。この div は、この部分ビュー ファイルではなく、Index.cshtml ファイルにあります。

したがって、まだ見ていないのは、CustomerController と BillingCustomerController の Edit ActionResult だけです。ここにカスタマーコントローラーがあります

public class CustomerController : Controller
{
    [HttpGet]
    public PartialViewResult Edit(Guid customerId)
    {
        var model = new Customer {
            CustomerId = Guid.Empty, 
            Name = "Mike McCarthy"};

        return PartialView("_Customer", model);
    }

    [HttpPost]
    public ActionResult Edit(Customer customer)
    {
        return PartialView("_Customer", customer);
    }
}

この投稿では複合 UI の構築を直接扱っているため、このコントローラーでは実際に「起こっている」ことは何もありません。「PartialView」を介して戻り、使用する部分ビューの名前と、ビューがレンダリングする必要がある必要なモデルを指定する方法に注目してください。

これが BillingCustomerController です

public class BillingCustomerController : Controller
{
    [HttpGet]
    public PartialViewResult Edit(Guid customerId)
    {
        var model = new BillingCustomer {
            CustomerId = Guid.Empty, 
            IsOverdueForPayment = true };

        return PartialView("_BillingCustomer", model);
    }

    [HttpPost]
    public PartialViewResult Edit(BillingCustomer billingCustomer)
    {
        return PartialView("_BillingCustomer", billingCustomer);
    }
}

ここでも CustomerController と同じですが、このコントローラーが BillingCustomer エンティティを処理しているという点が異なります。

HomeController の Index ActionResult をロードすると、次のような画面が表示されます。

複合UI

各 [保存] ボタンは、ページ全体の通常のポストバックを発生させることなく、部分ビューがデータを取得するために更新して対話する必要があるコントローラーへの非同期ポストバックを実行します。どちらの保存ボタンを押しても、DateTime スタンプが変更されないことがわかります。

これが、部分ビューを使用して最初の複合ビューを構築する方法でした。私はまだMVC3に非常に慣れていないので、何かを台無しにしたり、必要以上に難しい方法で何かをしたりする可能性がありますが、これが私がそれを機能させた方法です.

于 2012-10-01T16:32:24.850 に答える