I understand how to use Partial Views, and I understand Ajax.ActionLink and Ajax.BeginForm when it comes to how to set those up in the view. I’m assuming each partial view has it’s own controller. I’m thinking bounded context here, as in each partial view could talk to it’s own bounded context via its own controller
I guess the piece I’m missing is:
- how to have partial views included in a “master view” (or holding view) and have each of these partial views independently post to a separate controller action, and then return to refresh the partial view WITHOUT loading the “master view” or holding view.
- the “master” view or holding view still needs to have its own controller, I want to keep the master controller from reloading its view, and let the view that is produced by an action method of the master controller hold a reference to these two partial views.
There are two approaches it seems I can take, one is to use the “Ajax.” functionality of MVC3, the other is to use straight-up jQuery and handle all this interaction by hand from the client side.
Is what I’m trying to do possible both ways, or is one way “better suited” to this type of composite ui construction?
So far, the only things I have seen are trivial examples of composite ui construction like a link via an Ajax.ActionLink that refreshes a single on the page, or a form written as an Ajax.BeginForm that repopulates a div with some content from a partial view.
Okay, so I finally have some working code that I think is the right way to do it. Here is what I went with. I have a two simple “entities”; Customer and BillingCustomer. They’re really meant to be in separate “bounded contexts”, and the classes are super-simple for demostration purposes.
Note that both classes reference CustomerId, which for the sake of this demo, is a GUID.
I started with a simple HomeController that builds a ViewModel that will be utilized by the Index.cshtml file:
The CompositeViewModel class is just a dumb DTO with a property for each domain entity, since the partial views I’ll be calling into in my Index.cshtml file each need to pass their respective domain model into the partial view:
Here is my resulting Index.cshtml file that uses the Index method on the HomeController
A couple things to note here:
entity, and passes in the appropriate entity. Careful with the
syntax here for the Html.Partial call!
So, here is the _Customer partial view:
the important part here is the Ajax.BeginForm call. Note that it’s explicitly calling the Edit ActionMethod of the CustomerController. Also note that the UpdateTargetId is set to “customerDiv”. This div is NOT in the partial view, but rather in the “parent” view, Index.cshtml.
Below is the _BillingCustomer view
Again, note that UpdateTargetId is set to billingCustomerDiv. This div is located in the Index.cshtml file, not this partial view file.
So, the only thing we haven’t looked at yet is the Edit ActionResult on the CustomerController and the BillingCustomerController. Here is the CustomerController
There is nothing really “happening” in this controller, as the post deals directly with building a composite UI. Notice how we’re returning via “PartialView” and specifying the name of the partial view to use, and the required model the view needs to render.
Here is BillingCustomerController
Again, the same as CustomerController, except for the fact that it’s this controller is dealing with the BillingCustomer entity.
Now when I load up my HomeController’s Index ActionResult, I get a screen that looks like this:
Each Save button will do an async postback to the controller the partial view needs to update and talk to in order to get data, all without causing a regular postback for the whole page. You can see the DateTime stamp does NOT change when hitting either save button.
So, that’s how I went about building my first composite view using partial views. Since I’m still very new to MVC3, I could still be screwing something up, or doing something in a way that is harder than it needs to be, but this is how I got it working.