Client Rendering Views with Spark and ASP.NET MVC

Thursday, March 12, 2009

Spark is a view engine for the ASP.NET MVC and Castle Monorail frameworks. I’ve been wanting to try this creation by Louis DeJardin for some time, but ScottW pushed me over the edge with “If you are using ASP.Net MVC, you owe yourself to spend some time with Spark”. The Spark documentation makes it easy to get started, and the source code and examples are even more valuable.

There are quiet a few tutorials for Spark floating around, but I wanted to call out what appears to be a well hidden secret in the samples: the client rendering of views. In short, the client rendering produces JavaScript you can invoke on the client to render the same HTML you see when rendering a server-side partial view. This means you can happily fetch JSON from the server and use it to produce HTML without duplicating the server-side template logic on the client.

As an example,let’s say you have the following partial view to render the employees inside a department:

<div id="employees">
  <table>
    <tr>
      <td>ID</td>
      <td>Name</td>
    </tr>
    <viewdata department="Models.Department"/>
    <tr each="var employee in department.Employees">
      <td align="right">
        ${employee.ID}
      </td>
      <td>${employee.Name}</td>
    </tr>
  </table>
</div>

Notice how in Spark you can weave C# into the markup without breaking the flow of the HTML.

Next, let’s say you wanted the ability to refresh just this partial section of your view by asynchronously fetching data from the server. A first step would be to create a controller action that returns a Spark JavascriptViewResult.

public ActionResult ShowEmployees()
{
    return new JavascriptViewResult {ViewName = "_ShowEmployees"};
}

This action tells Spark to generate some JavaScript code from the _ShowEmployees partial view (the one we see above). The JavaScript will know how to create the same HTML as the server side view. Since this action produces JavaScript, you'll want to add a <script> in your main view that references that action endpoint. (this is reminiscent of how ASP.NET AJAX produces WCF proxies in JavaScript that know how to invoke service endpoints on the server, except client rendering isn’t about services – it’s about sharing a data binding template logic between the client and server).

<content:head>
...
<script type="text/javascript" src="~/Department/ShowEmployees"></script>
</
content:head>

What you’ll receive in your view is a JavaScript object with a RenderView method, and the RenderView method knows how to take your view model (as JSON data) and create the same HTML as the server-side partial view. Combining this generated JavaScript object with jQuery’s AJAX capabilities is straightforward.

$.getJSON(
  "/Department/Refresh/" + $("#id").val(),
  function(data) {
    var content = Spark.Department._ShowEmployees.RenderView(
                     { department: data });
    $("#employees").html(content);
});

The above code gets a JSONified version of your view model from the server and passes it into RenderView. RenderView returns the HTML we can use to update the UI. Clever!

For more on Spark, check out Lou’s blog.


Comments
Louis DeJardin Thursday, March 12, 2009
Gotta hate it when the docs are stale enough for a features to become an easter egg. :)
Ben Scheirman Thursday, March 12, 2009
Aaron Jensen gave a good demo of Spark at ALT.NET Houston, which I recorded here: http://kyte.tv/benscheirman

Crappy recording, but it's watchable. Starts at about the 3 minute mark.
scott Thursday, March 12, 2009
@Ben - Awesome!
Louis DeJardin Thursday, March 12, 2009
I believe there's also another recording that was posted later... Let's see...

http://vimeo.com/3464511
Ben Cherry Friday, March 13, 2009
Oooh, that's really cool. Somehow I had never heard of Spark before, but I'm definitely going to check it out. This is a really clean solution to a problem I keep running into these days. I wish I could convince one of my clients to let me rebuild their front-end with MVC...
Ben Cherry Tuesday, March 17, 2009
Thanks again for the post! It's difficult to find good material on Spark out there.

I actually took your method and used it in one of my own projects. I extended what you wrote here to allow graceful degradation of the AJAX functionality for my appliction. If anyone's interested in how (it's pretty simple), I wrote a quick post about it on my blog.
scott Tuesday, March 17, 2009
gravatar Marshal Thursday, December 3, 2009
Pretty awesome although it appears to have some issues. Spark conditionals (if's) cause the client rendering to fail.
gravatar Vegas Casino Tuesday, February 9, 2010
You can programatically change the page, but you need to use the MasterType directive with a type name (not a virutal path), and make the type you point to a base class for your master pages.
gravatar serdar Tuesday, April 6, 2010
I will start using Spark...
Comments are now closed.
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!