Here is one approach.
You have a separate WebAPI controller for handling the data access from the clientside.
//Inside your CommentsApiController, for example
public IEnumerable<Comment> Get(int id)
{
var comments = _commentsService.Get(int id); //Call lower layers to get the data you need
return comments;
}
Your MVC controllers have actions which return PartialViewResults. It is a simple action which returns a partial view.
//Inside your MVC CommentsController, for example
public PartialViewResult CommentsList(int id)
{
return PartialView(id);
}
Your partial view renders out your markup, with knockout bindings. We make a unique ID for our HTML so we can bind our knockout viewmodel to this specific section of the page (avoid conflicting with other knockout components on the page).
The JavaScript we require (knockout viewmodels etc) gets included, a new ViewModel created and knockout bindings applied.
@{
var commentsId = Model; //passed from our MVC action
var uniqueIid = System.Guid.NewGuid().ToString();
}
<section class="comments" id="@uniqueIid ">
<ul data-bind="foreach: { data: Comments, as: 'comment' }">
<li>
<span data-bind="text: comment.Author"></span>
<p data-bind="text: comment.Message"></p>
</li>
</ul>
</section>
@Scripts.Render("~/js/comments") //using MVC Bundles to include the required JS
@{
//generate the URL to our WebAPI endpoint.
var url = Url.RouteUrl("DefaultApi", new { httproute = "", controller = "Comments", id = commentsId });
}
<script type="text/javascript">
$(function() {
var commentsRepository = new CommentsRepository('@url');
var commentsViewModel = new CommentsViewModel(commentsRepository);
var commentsElement = $
answered 2013-07-04T11:21:49.787