Unfortunately, this is pure HTML hosting, so it isn't possible to properly show this tutorial. Code is below, for interactive version please go to http://learn.knockoutjs.com/#/?tutorial=webmail
Also, you can see generated javascript using developer tools of your preferred browser
namespace MVCTest
{
[ViewModel]
public class SPAViewModel
{
[Record]
public class Mail
{
public Id : int { get; set; }
public From : string { get; set; }
public To : string { get; set; }
public Date : string { get; set; }
public Subject : string { get; set; }
public MessageContent : string { get; set; }
public Folder : string { get; set; }
}
[Record]
public class FolderData
{
public Id : string { get; set; }
public Mails : IEnumerable[Mail] { get; set; }
}
public Folders : List[string] { get; set; }
public ChosenFolderId : int { get; set; }
public ChosenFolderData : int { get; set; }
public ChosenMailData : int { get; set; }
public this()
{
Folders = ["Inbox", "Archive", "Sent", "Spam"].ToList();
js self = this;
js <#
Sammy(function() {
this.get("#:folder", function() {
self.ChosenFolderId(this.params.folder);
self.ChosenMailData(null);
$.get("/SPAViewModel/Folder", { folder: this.params.folder }, function(result) {
self.ChosenFolderData(ToTypedObject(result))
});
});
this.get("#:folder/:mailId", function() {
self.ChosenFolderId(this.params.folder);
self.ChosenMailData(null);
$.get("/SPAViewModel/Mail", { mailId: this.params.mailId }, function(result) {
self.ChosenMailData(ToTypedObject(result))
});
});
this.get('', function() { this.app.runRoute('get', '#Inbox') });
}).run();
#>;
}
public GoToFolder(folder : int) : void {
js location.hash = folder;
}
public GoToMail(mail : Mail) : void {
js location.hash = mail.Folder() + '/' + mail.Id();
}
public class Server
{
allMail : list[Mail] = [
Mail(1, "Abbot \u003coliver@smoke-stage.xyz\u003e", "steve@example.com", "May 25, 2011", "Booking confirmation #389629244", "", "Inbox"),
Mail(2, "Addison Begoat \u003cupton.oprdrusson@pear-income.xyz\u003e", "steve@example.com", "May 7, 2011", "FW: Associate advice", "", "Inbox"),
Mail(3, "Allistair \u003cleroy72@plane-railway.xyz\u003e", "steve@example.com", "May 19, 2011", "RE: Phone call tomorrow 5 o\u0027clock", "", "Inbox"),
Mail(4, "(archived) Abbot \u003coliver@smoke-stage.xyz\u003e", "steve@example.com", "May 25, 2011", "Booking confirmation #389629244", "", "Archive"),
Mail(5, "(archived) Addison Begoat \u003cupton.oprdrusson@pear-income.xyz\u003e", "steve@example.com", "May 7, 2011", "FW: Associate advice", "", "Archive")
];
public Folder(folder : string) : FolderData
{
FolderData(folder, allMail.Where(m => m.Folder == folder));
}
public Mail(mailId : int) : Mail
{
allMail.FirstOrDefault(m => m.Id == mailId);
}
}
}
public partial module Views
{
[View()]
public SPAView(viewModel : SPAViewModel) : string
{
_ = viewModel;
<#
<div xmlns="">
<ul class="folders" data-bind="foreach: Folders">
<li data-bind="text: $data,
css: { selected: $data == $root.ChosenFolderId() },
click: $root.GoToFolder"> </li>
</ul>
<table class="mails" data-bind="with: ChosenFolderData">
<thead><tr><th>From</th><th>To</th><th>Subject</th><th>Date</th></tr></thead>
<tbody data-bind="foreach: Mails">
<tr data-bind="click: $root.GoToMail">
<td data-bind="text: From"> </td>
<td data-bind="text: To"> </td>
<td data-bind="text: Subject"> </td>
<td data-bind="text: Date"> </td>
</tr>
</tbody>
</table>
<div class="viewMail" data-bind="with: ChosenMailData">
<div class="mailInfo">
<h1 data-bind="text: Subject"> </h1>
<p><label>From</label>: <span data-bind="text: From"> </span></p>
<p><label>To</label>: <span data-bind="text: To"> </span></p>
<p><label>Date</label>: <span data-bind="text: Date"> </span></p>
</div>
<p class="message" data-bind="html: MessageContent"> </p>
</div>
</div>
#>
}
}
}