Knockout with MVC Sample

I have an application where there exists the ability to request invitation to a group, similar to the process of joining a private linked in group.  One of my MVC views displays all such requests, and allows the user to process them.  The way this page works is the following: the view loads with no data.  The view begins to build the view model and bind it without any request data.  A JQuery AJAX request fetches the request data from the server, and loads the requests after-the-fact, once the AJAX request completes.  The process used an action method to stream JSON to the client, and returns the following content:

public ActionResult Invitations(string username)

{
.
.
//load data from server

return Json(new
{
Invitations = from i in requests
select new
{
i.Key,
i.GroupName,
i.UserName,
i.Note
}
});
}

On the client, we have a view defined as the following.  there is a lot of markup, but the process isn’t overly complex.  At the top, we have the template user interface defined.  Later on, we construct the view model, load it with empty data.  An AJAX request retrieves JSON data and loads the invitations into the view.  Each invitation displays the core information, along with a button that permits and acceptance or rejection of the invitation.

<div class=“P”>

<div databind=“if:hasInvitations”>
<div id=“InvitationsList” databind=“template: { name: ‘InvitationsTemplate’, data: invitationsList }”></div>
</div>

<div databind=“if:hasNoInvitations”>
Loading
</div>

<div databind=“if:emptyInvitations”>
No invitations have been submitted yet.
</div>

</div><script type=“text/html” id=“InvitationsTemplate”>

<section databind=“foreach:Invitations”>
<h3 databind=“html:UserName”></h3>

<div class=“P”>
For Group <span databind=“text:GroupName” />
</div>

<div class=“P”>
The user attached the following note:
<div databind=“html:Note”></div>
</div>

<div class=“P”>

<div>
Please approve or reject the user using the buttons below.
</div>

<div>
<form class=“InlineForm” action=‘@Url.Action(“Approve”, “Groups”)’ method=“post”>
<input type=“submit” value=“Approve” />
</form>

<form class=“InlineForm” action=‘@Url.Action(“Reject”, “Groups”)’ method=“post”>
<input type=“submit” value=“Reject” />
</form>
</div>

</div>

</section>

</script>

<script type=“text/javascript”>

function viewModel() {
var self = this;

self.invitationsList = ko.observable(null);

self.emptyInvitations = ko.computed(function () {
var i = self.invitationsList();

   return (i != null && i.Invitations.length == 0);

});

self.hasInvitations = ko.computed(function () {
var i = self.invitationsList();

    return (i != null && i.Invitations.length > 0);

});

self.hasNoInvitations = ko.computed(function () {
    return self.invitationsList() == null;
});

}

var model = new viewModel();
ko.applyBindings(model);

$.ajax({

type: “post”,
url: ‘@Url.Action(“Invitations”, “Groups”)’,
data: { UserName: ‘@ViewBag.UserName’ },
context: model,
success: function (d) {
this.invitationsList(d);
}

});

</script>

Notice the computed properties; at first, the list of invitations is null, meaning we haven’t gotten any invitations at all.  If I would have bound a null observable to the view, Knockout JS throws an exception in relation to this.  We can’t bind a null observable that isn’t prevented first with some if logic.  If we do have data, one of two view appears.  Either the view renders the invitations posted, or if an empty list, we see an empty message to inform the user the system has no invitations.

This is a piece of functionality I actually have in operation, and I hope this may be of benefit to you to see how an entire view may be implemented in Knockout.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s