Well done that man!Every now and then I'm thinking to myself "wouldn't it be nice if you could do x..." And then I discover that someone else has thought the self same thoughts and better yet they have the answer! I had this situation recently and discovered the wonderful Kevin Craft had been there, done that and made the T-shirt. Here's his blog:
I wanted to talk about how this simple post provided me with an elegant solution to something I've found niggling and unsatisfactory for a while now...
How it helpedJust last week I was thinking about
Partial Views. Some background. I'm working on an ASP.NET MVC 3 project which provides users with a nice web interface to manage the workflow surrounding certain types of financial asset. The user is presented with a web page which shows a kind of grid to the user. As the user hovers over a row they are presented with a context menu which allows them to perform certain workflow actions. If they perform an action then that row will need to be updated to reflect this.
Back in the day this would have been achieved by doing a full postback to the server. At the server the action would be taken, the persistent storage updated and then the whole page would be served up to the user again with the relevant row of HTML updated but everything else staying as is.
Now there's nothing wrong with this approach as such. I mean it works just fine. But in my case since I knew that it was only that single row of HTML that was going to be updated and so I was loath to re-render the whole page. It seemed a waste to get so much data back from the server when only a marginal amount was due to change. And also I didn't want the user to experience the screen refresh flash. Looks ugly.
Now in the past when I've had a solution to this problem which from a UI perspective is good but from a development perspective slightly unsatisfactory. I would have my page call a controller method (via
jQuery.ajax) to perform the action. This controller would return a
JsonResultindicating success or failure and any data necessary to update the screen. Then in the
successfunction I would manually update the HTML on the screen using the data provided.
Now this solution works but there's a problem. Can you tell what it is yet? It's not very DRY. I'm repeating myself. When the page is initially rendered I have a
I was recently thinking that it would be nice if I could refactor my row HTML into a
Partial Viewwhich I could then use in 2 places:
- In my standard
Viewas I iterated through each element for display
- Nested inside a
$("myRowSelector") .empty() .html(data.RowHTML); //Where RowHTML is the property that //contains my stringified PartialViewand if I later make changes to the
On the grounds that someone else might have had the same idea I did a little googling around. Sure enough I discovered Kevin Craft's post which was just the ticket. It does exactly what I'd hoped.
Besides being a nice and DRY solution this approach has a number of other advantages as well:
- Given it's a
Partial Viewthe Visual Studio IDE provides a nice experience when coding it up with regards to intellisense / highlighting etc. Not something available when you're hand coding up a string which contains the HTML you'd like passed back...
- A wonderful debug experience. You can debug the rendering of a
Partial Viewbeing rendered to a string in the same way as if the ASP.NET MVC framework was serving it up. I could have lived without this but it's fantastic to have it available.
- It's possible to nest *multiple*
Partial Viewswithin your
JsonResult. THIS IS WONDERFUL!!! This means that if several parts of your screen need to be updated (perhaps the row and a status panel as well) then as long as both are refactored into a
Partial Viewyou can generate them on the fly and pass them back.