Asp.net mvc 3 如何在MVC3中构建复合UI?

Asp.net mvc 3 如何在MVC3中构建复合UI?,asp.net-mvc-3,partial-views,bounded-contexts,Asp.net Mvc 3,Partial Views,Bounded Contexts,我了解如何使用局部视图,我也了解Ajax.ActionLink和Ajax.BeginForm如何在视图中设置它们。我假设每个局部视图都有自己的控制器。我在这里考虑的是有界上下文,因为在每个局部视图中,都可以通过自己的控制器与自己的有界上下文对话 我想我缺少的是: 如何将部分视图包含在“主视图”(或保留视图)中,并将这些部分视图中的每一个独立地发布到单独的控制器操作,然后在不加载“主视图”或保留视图的情况下返回刷新部分视图 “主”视图或保持视图仍然需要有它自己的控制器,我想防止主控制器重新加载它的

我了解如何使用局部视图,我也了解Ajax.ActionLink和Ajax.BeginForm如何在视图中设置它们。我假设每个局部视图都有自己的控制器。我在这里考虑的是有界上下文,因为在每个局部视图中,都可以通过自己的控制器与自己的有界上下文对话

我想我缺少的是:

  • 如何将部分视图包含在“主视图”(或保留视图)中,并将这些部分视图中的每一个独立地发布到单独的控制器操作,然后在不加载“主视图”或保留视图的情况下返回刷新部分视图
  • “主”视图或保持视图仍然需要有它自己的控制器,我想防止主控制器重新加载它的视图,并让主控制器的操作方法生成的视图保持对这两个部分视图的引用
  • 我似乎可以采取两种方法,一种是使用MVC3的“Ajax”功能,另一种是直接使用jQuery并从客户端手动处理所有这些交互

    我试图做的是两种方式都可能,还是一种方式“更适合”这种复合ui构造


    到目前为止,我所看到的只是复合ui构造的一些小例子,比如通过Ajax.ActionLink刷新页面上的单个页面的链接,或者以Ajax.BeginForm形式编写的表单,该表单使用部分视图中的某些内容重新填充div。

    好的,所以我终于有了一些工作代码,我认为这是正确的方法。这是我要的。我有两个简单的“实体”;客户和账单客户。它们实际上是在单独的“有界上下文”中,为了演示的目的,这些类非常简单

    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,在本演示中,CustomerId是一个GUID

    我从一个简单的HomeController开始,它构建了Index.cshtml文件将使用的ViewModel:

    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; }
    }
    
    @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>
    }
    
    下面是我的结果Index.cshtml文件,它使用HomeController上的Index方法

    @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>
    
    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);
        }
    }
    
    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);
        }
    }
    
    在这个控制器中没有什么真正的“发生”,因为本文直接涉及构建复合UI。注意我们如何通过“PartialView”返回并指定要使用的部分视图的名称,以及视图需要渲染的所需模型

    这是BillingCustomerController

    @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>
    
    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);
        }
    }
    
    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时,我会看到如下屏幕:

    每个保存按钮都会向控制器执行异步回发,部分视图需要更新并与之通信,以获取数据,所有这些都不会导致整个页面的常规回发。点击任一保存按钮都可以看到日期时间戳没有改变


    所以,这就是我如何使用局部视图构建我的第一个复合视图。因为我对MVC3还是一个新手,所以我可能仍然在搞砸一些事情,或者以比需要更困难的方式做一些事情,但这就是我让它工作的方式。

    是的,两者都有可能。我从来没有真正尝试过Ajax助手,我只使用过jQueryAjax。我使用部分视图的合成来包含功能。例如,一个控制器返回一个视图,该视图由较小的部分组成,用于加载联系人和相关数据,而另一个控制器则对来自控制器的数据进行操作。这意味着我也可以在其他领域使用我的联系人和观点