Doing SPA with Knockout
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Castro, Miguel A.
SPA stands for single-page-application and it’s a little bit of a misunderstood term. IT does not imply that the entire web application be a single page. SPA is more of a style applied to parts of a site, and knockout is the perfect technology for tackling on this modern way of writing web applications. In this session I’ll show you how to mix ASP.NET MVC with KnockoutJS to develop web applications that stand strong in today’s world of rich, interactive sites. But it won’t be limited to just these two technologies. You see in order to keep things on a single page that flips around different modes, you need to go quietly to the server without anybody knowing (shhh), and for that I’ll throw in the Web API. In the end you’ll be able to write apps that get a server view when they need to using MVC then stay on the client and flip around multiple modes using Knockout, and remember, keep it quiet that I’ll be using Web API to do alittle bit server access.
 All right, is this thing, yeah, it's loud enough. Okay. Good morning everybody. How do you say good morning in Norwegian? That's exactly what I just said. Say it again? Seriously, say, how do you say it? More? Wow, pretty close. I don't know any Norwegian whatsoever. How do we know how to say yes or no? Which is probably a good thing. Thanks for coming in this morning. We're going to talk about SPA with Knockout. Any Knockout users in here? Has anybody heard of Knockout but not quite gotten there yet? Looking forward to seeing maybe a little demo, a little primer? Because I have one for you. I'm going to spend just a little time giving you a Knockout primer. It's a great technology. If you haven't gotten involved in it, if you're doing MBC, or if you're doing any kind of web development, you haven't gotten involved in any of the MBVM frameworks, you really owe it to yourself to look at them. And hopefully I will inspire you to do so. Because we only have an hour to spend together, so I want to leave you with just enough information so you can leave and continue learning this stuff. So my name is Miguel Castro. This is a special picture that I put together for you guys. I don't use it anywhere else in the world except Norway. My good friend Johnny over there sitting in the middle of the crowd is the one responsible for giving me that helmet, which freaking almost broke my nose. I don't know how the Vikings did it, but this thing weighs like 20 pounds. And you put it on your head and as soon as you nod, it falls down and it hits the bridge of your nose and you break your nose. So thanks Johnny, you bastard, you almost broke my nose. But it was a wonderful gift. The only problem is it doesn't make it through airport security unless you put it inside your bag. Because you can probably break right through the airplane cockpit with this thing. You put it on your head and just crash right through. So who's attended one of my talks at NBC before? I'm going to go ahead and talk about it. I'm going to talk about it before. Alright, mostly new people. That's good. I like that. Anybody ever see me in any other conference in the US? In Florida, in Orlando. What the hell did I do in Orlando? Oh yeah, VS Live. That's a good conference. That's one of my regular ones. That's one of my favorite conferences. That and this. I got to say that. NBC is one of my favorite conferences. I love Oslo. Very helpful today. So we're going to talk about knockout and SPA. Primarily SPA. But I got to give you a little intro to what that is. Because it's one of those terms that's not properly defined. And I want to make sure you understand exactly what it is before you understand how to use it. We're going to talk about NVVM first. Just very briefly through a couple of slides. Then I'm going to spend probably about 15, just 15, 20 minutes tops giving a knockout primer to you guys. Mainly because I anticipated that a lot of hands would go up when I asked a question who's not used knockout before. This is an attractive subject. But unfortunately for me to jump right into what SPA is, you have to have kind of a basic understanding and fundamentals of what knockout is. So I'll be spending just a little bit of time on that. And then we'll get into SPA and I have a couple of different techniques that I use for SPA. Who's done any kind of SPA programming with knockout? Or with anything else? It's pretty cool. Once you start doing it, you don't want to do websites any other way. It brings a level of richness that until recently we only had in desktop applications. If you use WPF or Silverlight, you get really rich UIs. We couldn't do that easily in the web before. And now we can. There's one additional topic I want to throw in here at the end of the day and that's browser history. Because when you're doing SPA, keeping track of browser history becomes very important. So I'll get into more details on that and you'll understand what I mean later. So basically what MBVM is, if you've never done it before, it's just a pattern. It's an architectural pattern for separating UI logic from UI. It is not the separation of business logic. That's a really, really bad definition. And I see that definition too often where you read a book about what MBVM is and it says MBVM is a pattern that separates the business logic from the UI logic. That's bullshit. It's not. We've been doing layered applications for a very long time where you have UI business and data tier. That's separating business logic. MBVM takes the UI layer only and it separates it into logical and physical design. So a view model is essentially just a logical representation of the user interface. All of the elements on the user interface that are physical and all of the actions that a user interacts with, those are represented logically in a view model through behaviors and properties. It's at the heart of XAML programming. Who does any kind of XAML here at all? Whether Silverlight WPF or Metro. Okay. I still call it Metro. I like that term. Microsoft can sue me over it rather. If you're not doing XAML, if you're doing XAML without MBVM, in my opinion, you're doing it wrong. So you really owe it to yourself to learn what that is. This until recently, it's all about state-drivenness, meaning you change state in the view model and then it reflects in the view through binding. Those of you that raise your hands with XAML, you understand what this means. You know, you do everything through binding and you change a little bit of state and poof, the UI just changes magically. That's at the heart of what MBVM is, a state-driven development. Until recently, this was not really possible on the web in an easy way or a good way. The web for a very long time has tried binding through different iterations from old ASP to ASP10 and then ASP20. And every iteration, it gets a little better, just a little bit. But it doesn't really get all the way there. And with these JavaScript frameworks that have surfaced over the past year and a half or so, it's gotten there, in my opinion. A knockout is my favorite. It's the one that I like to use. There are several on the market. There's another one out there you might have heard of called Angular. AngularJS. There's one called Backbone. So there's several frameworks out there and they're all very, very good. I just happen to like knockout because I like the way it works. It's just a personal preference. It's like saying C sharp versus VB. Alright, maybe no. Who does VB development in here? There you go. Everybody just stare at this guy. VB's great, man. I had a great career with VB. Never want to do it again in my life. So what knockout is, that knockout is what allows us to do MBVM type development, which you're going to get a demo of in the web world. I set the web world because it's not really the Microsoft world. Knockout was developed by one person originally. A guy named Steve Sanderson. Brilliant guy, works from Microsoft. And he wrote the framework before he came into Microsoft. And he brought it with him and it became so successful. It was such a big hit that Microsoft actually puts it into the NBC templates now. So when you add a new NBC4 application to your projects, to your solution, you will get the knockout libraries automatically in there. There is another library that we're going to get pretty soon automatically. It's called Bootstrap. Who's heard of Bootstrap? Twitter Bootstrap. It's pretty cool, isn't it? I mean, it's just an easy way of getting real professional looking web CSS without a lot of work. Bootstrap's going to become part of the NBC project template as well. So knockouts were written entirely in JavaScript and it's got no dependencies on Microsoft. In fact, if you go to knockoutjs.com, which is probably the best source that you can go to for knockout training, that and the plural side courses, you'll see that it's not an NBC site. It's nothing but HTML and JavaScript. So it has no dependency. However, in my opinion, NBC is a great delivery platform for it. NBC, the NBC framework becomes the deliverer of the JavaScript and the HTML. And I don't think anything can deliver HTML much better. than NBC when you start mixing all the C-sharp stuff that you can do with it. So that's what I'm going to be using to deliver my knockout and my HTML. Knockout works with data dash tags. This is how we do our binding. You'll see that in a second. And it's easy to install because it's available as a new get package. And like I said, it's already there when you add a new NBC 4 app. Maybe not up to date, so you have to go to new get and do an update. But it's very, very easy to install. It works through this concept of observables. And this is what MVVM is about. It's about observability. In the XAML world, for those of you that are XAML developers, you've heard of property change notification. That's the same thing as what I say, observables. It's all about this concept of the view of subscribing to the view model and saying, let me know when something has changed. So when a property changes in the view model, the view automatically updates. That's the beauty of MVVM is that we're not directly interacting with the view. We're just changing state in the view model and acting upon actions in the view model. And automatically the view changes. And if done right, it actually can be a very, very elegant way of developing. I'm going to jump right to the knockout demo, so I don't waste a lot of time. But you're going to see that it's not as difficult as a lot of people think. I do a whole hour session on just knockout. Unfortunately, it wasn't chosen for this conference. So let me, I already have a pre-canned one, and that's what I'm going to bring up. So how's this font for people in the back? Should I make it bigger? Yes? Okay. You want bigger, you got bigger here. Is that better? Anybody need bigger than that? Okay. Can everybody see me standing on stage? Just want to make sure. Alright, so this is a sample knockout view model. Now without getting, when I do my whole hour on knockout, I get into the step by step. And I build it from scratch and I build small ones first, or just a couple of properties, then I make it bigger and bigger. I just want to head to a full blown one here so you can see that I'm just going to head to a full blown one here so you can just get the idea, because this is nothing but a little 50 minute primer that we're going to do. But this is essentially just a JavaScript function. Everything in knockout is a JavaScript function starting with the top, which is the view model. So this is my view model here, it's just a JavaScript function. And then I'm declaring the properties. In knockout, when you create a view model is just like in XAML when you create a view model, you create a class that has properties in it. And that property becomes your state, because that's what the view is going to bind to. This is no different. It's an exact correlation. So I basically just have a couple of properties here, one called person and one called people. And notice person is just a single object. And it's an object of this other type here, called person model. So it's no different than creating a property that's a type person model class, if you were doing this in C sharp. This is just a JavaScript version of this. And then you got this other object here called people, which is an array. This is in C sharp, this would be the equivalent of creating an observable collection. Everybody know what an observable collection is in C sharp? It's what we use in MBVM. So then the rest are all just functions. And what I have here, for example, is that I have a function called load people. All load people is doing is going out to a web API call and getting information. This is how you would get data in knockout, because the whole idea is that the view is going to ask the view model to do something. In my case, it's going to ask the view model to load some people. So whenever the view calls this function, I'm going to actually make a rest call to a web API. And without getting into any kind of web API details here, this is just a web API controller. There it is right there. It's called data. And it's got a method in there called get where I'm building my list. Obviously in the real world, this would all come from a database. I cheated it. I just created a list of some developer friends that I know. And I bring that back. So there's my API slash data, which is going to here. And I bring back that result. And then this is the interesting part. Notice what I'm doing. In knockout, what I'm doing is that I'm taking the result. Now this is a regular API call that returns JSON. As simple as that. This is just an Ajax call. This here has nothing to do with a knockout. Anybody recognize what this is? It's jQuery. It's a standard jQuery call. If you don't want to use jQuery, if you have another library that you use to make Ajax calls, by all means, use that instead. All I'm doing is mixing libraries here. So I'm making an Ajax call, and then I'm getting the JSON result back. And all I'm doing here is that I'm telling knockout, turn that JSON result into the array self people that you saw that I declared up here. Because it's now creating a bunch of observables. This coyomapping here is a knockout plugin that turns JSON result into an observable array. Now that's all I'm doing is I'm creating this observable. But the whole idea of MVVM is that as soon as we change something in the state, if there's anything in the view that's bound to that, it's going to reflect right away. So just the act of me creating this variable without doing anything to it, is going to immediately do something. Because if I go over to my view, in my view, notice I'm loading in my view model JS here, and now I'm binding it here. This is the equivalent of your, and I'm making comparisons to XAML because I had quite a few XAML people here, and it's kind of the world that I come from. I come from the XAML world originally. So what this code is doing is it's instantiating the view model and binding it to the view. In XAML, this would be the equivalent of taking the data context property and binding it to the copy of the view model. Everybody know what I'm talking about there when I say data context? If you're a C sharp person, that's exactly what this is. I'm targeting the KO demo, which is this right here. So this is like saying give me the div data context and binding it to that view model. Now what I've done here, and this is where it starts to get really cool, is that that entire view model with all its properties and all its actions, all its functions, is now available for binding from this level and down. Just like a visual tree in XAML applications. So now remember the property that I just changed? I changed the property called people, right? By me filling up this property, if anything here was listening to that, it will automatically reflect. And as you can see, I have a div tag where I'm data bound here. Where's the, nope, that's not the one, sorry, right here. I have a table, very simple table, where the body of the table is data bound to the people. And I'm just doing a for each. So now inside, I can say, bind this TD to the first name property, this TD to the last name property. And that's under the assumption that the people collection has objects in it that have a first name and last name property. Which in my case they do, because the JSON that is being resulted here is being built by a C sharp object called person model, which has first name and last name. Which means when that JSON comes back to right here, it's going to be JSON representation of an array of first name and last name objects. So as soon as I turn that into a knockout observable array with this line of code right here, now the people collection is going to have objects that have first name and last name. So all I have to do now is just write my UI as simple as possible. Notice there's no code in here that says go get it, go load the people, build the list. I'm just showing you what the table looks like. And for, in the table I have a t body section with only one row. And all this is saying is that this is all going to be duplicated for however many people there are in that array. And any change that I make to the people, whether I change a person inside of it or add a new person to the array or delete one, is going to automatically refresh this. Because the framework, the knockout framework is overseeing this. There's no code here that shows you that. There's no code that shows you that as soon as a new person is added or a person is deleted, redraw this. The knockout framework does that automatically. This is exactly the same as is done in XAML. If you've done XAML binding before, you know that this is how it works. You do a list box in XAML, you define in the list box what one list item is going to look like. Which is what this is. One list item. And now you just rely on the view model changing. And as soon as the view model changes, whether it goes up or down, this is going to reflect automatically. Back to my view model. This load people. Notice these are all functions. But then at the bottom here, I'm calling load people. So as soon as the view model is instantiated, it defines all this. And then it sees this and it calls it. So it's going to go ahead and load the people. So just by loading this object right here, let me show you what I get. Let me show you what I get. At the risk of sounding completely geeky, knockout with NBC has not only made, to me, it's made getting back into the Web World a lot easier, but it's made it a whole lot of fun. It's actually fun to write what the hell it is. And then it's going to be a lot easier. And then it's going to be a lot easier. And then it's going to be a lot easier. It's actually fun to write, what the hell is going on here? subsid... It's made it fun to write Web applications again. env... audio audio Okay. Local host is not responding. Recover web page. Look at that. Leave it to Microsoft to go out to the Visual Studio to completely screw up what I'm in front of an audience. Huh? I should. Look at that. What the heck? This was working last night. You know what you got to do to a Windows program? Look, now it's not even closing. I think it's, it's a, I use crap. You know what you got to do to a Windows system to get it to mess up and start breaking shit on you? Absolutely nothing. No, you don't have to do a damn thing. Just leave it alone. Let's try Chrome. Alright, there we go. Good old Chrome, right? Jesus. Damn you, Microsoft. Hey, there's an, this room's pretty full. There's an overflow room, right? So there's supposed to be people watching this? Hey, I want to make sure that the overflow room can hear me. Can you guys just yell, hello, Miguel? Chicken? There's no balls in the overflow room. Alright. So look what I did. As soon as I did that, there's that table right there. You see how just drawing the HTML and drawing what a single item's going to look like and then binding it to the collection automatically repeated that part of the table however many times there were people. Now what else is there in that collection? Well, what I want this demo to do is I want it to be able to add new people and delete people from that collection. Well, this is the whole beauty of MBVM is that you don't think in terms of the view, you think in terms of the view model. So now that we have this logical representation of the view and forget about what the physical view looks like. Okay, the logical representation is a list of people. But now I want to be able to manipulate that list. So I don't have to think about how would I redraw that table in case I add a person? Or where would I add it? Or how would I remove a person? Forget about that. I just need to work with the collection, which makes it a lot easier because I think in logical terms only. I need to insert an item into the collection. I need to delete an item from the collection. And that's what these functions here do, add person. All I'm doing is that I'm creating a new person object that's coming from, and I'm not going to describe this now because it's getting into more knockout information that I'm ready to give you today. But a new person object is coming to this function and I'm taking that person object and I'm pushing it into the people collection. That's all I'm doing. Notice here, you don't see me manipulate the UI. You just see me manipulate that one collection. I'm inserting a new person into the people. Down here for delete, I'm removing that person from the people. All I'm doing is manipulating that collection. Now, this add person and delete person, these are actions. And in MVVM, you're not only buying to state properties, but you also buying to behavior. So your TDs and your allies and your spans and all that stuff can bind to property so they can physically display something. But your action elements like links or buttons can bind to behavior functions like add person or delete person. So if I go back to my HTML, you'll notice that up here, I have a text box that's bound to a property called first name of an object called person. And remember up here, I had an object called person and person is a type person model which has first name and last name. So person is something that has first name and last name. So here I'm saying with person, bind the text box to first name. This with, this is just so I don't have to say person.firstname and person.lastname. That's all it is. So I say with person, bind the text box and now that the text boxes are filled and they're bound to properties, anything that I type into the text box will automatically done for you by the knockout framework update these properties. So now that person object in the view model has names of people I typed into the text boxes. Now look at this button. This button is going to be bound to the add person function. So when I press the button, it's going to go to the add person function and because the button is inside the width, that's why the add person function receives that person here. And that's how I'm able to take the contents of the text box and add them to the collection. So by typing something into the text box, I automatically will get that into here and then I can just add it to the collection. And remember, the second that I added to the collection with no additional work on my part, the second I added to the collection, I should see it reflect here because this table is bound to that collection. So as soon as the collection changes, the view will automatically receive a message saying something that you're bound to has just changed. Please refresh yourself. Whether it goes, it changes to get bigger or changes to get smaller. And here, that table had a link next to each person that goes to the delete person. And remember, delete person is removing it from the collection. So the act of removing the person from the collection will automatically refresh this because I am affecting the collection that the view is bound to. Because it is observable. So with a very, very clean solution, no additional work on my part, look what can happen here. So I'll use my buddy Johnny back there. Where is Johnny? There he is. So I'm putting Johnny Beckham's name in here and as soon as I press add, you should see it added to the table. And there it is with no additional work. Now I'm going to delete Carl Franklin because he pissed me off the other day. And you can see that's gone. Now I'm deleting Richard. Now I can just add something else. And there's that something else. Now I can delete it. All I'm doing is manipulating the collection. The fact that the view is bound to the collection, it grows and shrinks dynamically without you doing any additional work. Tell me that's not like the cleanest little web page you've ever seen. It does complex stuff, but does it in a really, really clean fashion. Just take a step back and remove the knockout framework or anything you know about MBVM from this. And just picture how difficult it would be to do something like that. In traditional terms. Eating with using jQuery. You can do it with jQuery. And for those jQuery fanatics in the audience, you're probably saying, of course I can do it with jQuery. Yes, you can. But it's still not as clean as doing it like this because you'll have a lot of jQuery embedded code in your view. So things get more complex there. All right, that's my knockout primer. Any questions? Does it inspire you to go out and learn some knockout now? Because it's actually very, very cool. I never want to create an application without it again. I really don't. Somebody had a question? Yes. How are you? How would you, if you have the, you need to find a view or just finding other views based on view of can you bind CSS classes? Absolutely. Absolutely. You can bind a whole lot. I've only touched the surface of knockout because I don't have a lot of time. But I can bind any, any, knockout has some default bindings. Like the value binding, the text binding. But there's also a CSS binding. There's an HTML binding where it changes the whole inner HTML of that tag. So you can manipulate HTML in the view model and set it to a property and then have the HTML binding bind to that property. And now it changes the entire thing. This is what you would do in jQuery with inner HTML. So it's got all sorts of bindings. There's also a binding called ATTR attribute. So for any, any HTML attribute that doesn't have a built in knockout binding, you can use ATTR. So it's incredibly powerful. I really encourage you to go to either knockout.js, which will give you a nice little intro, but John Papa has a great course on plural site. Who's got plural site subscriptions here? All right. Those of you that didn't raise your hands, go down to the plural site booth and get a free month subscription. Definitely. I need the money. Actually, I'm working on a plural site course. It'll be out on July 31st. Yes, please go ahead. Unless I'm preempting your presentation, when you're combining this with ASP.NET MBC, are you just using the Web API there? Or are you using? I'm using Web API just for my Ajax calls, just to go out and get data. That's the only place that I'm using Web API here. Is that what you would use from MBC? You would just program the rest just using knockout in a single view? It doesn't have to be a single view. This is what I'm going to get into now. You are preempting the question a little bit. So this gentleman is segwayed nicely into what SPA is, because what I just showed you is a view that delivers something that then changes dynamically. It can be considered an SPA. What an SPA is, is short for single page application. And it's a real, real misuse of naming here. A misuse of nomenclature, because most people tend to think when you read about SPA, it's like, oh, wow, so now my whole application is going to be one view. In reality, that's not feasible, nor is it really easy to program. What SPA really is, it's about breaking your application down into sections. And each section being SPA driven. SPA is about the way we program MBVM with XAML, where we have one view, one window, that then changes the way it looks. But it doesn't mean you're going to have only one window in your whole application. My use of SPA is what I think is a more realistic and a much more manageable approach, is where I have separate views for each section of my site. So I may have a site that does e-commerce. So that site has a product catalog section, and it has a customer information section, it has a billing section, a bunch of different sites, other sections just like Amazon.com does. And each one of those delivers one view, and then uses knockout in the way that I'm going to teach you now to flip and switch the way that view looks. And that's what gives you the appearance of what SPA is, where you have one view, but instead of having that view refresh itself to the server to change the way it looks, it does that dynamically with knockout. Some people take this to the extreme, and they do the whole application like this, with one view and one view only. They get one page, one CSHTML page that delivers the whole application, and then the whole thing is done dynamically by knockout. Yes, you can do that, but it can get really, really complicated. I don't know if you want to put that kind of time into it. I certainly don't. So I SPA sections of my site, not the entire site. A good example of what SPA is out in the real world is Gmail. So if you use Gmail, you've seen a single page application in action, because Gmail refreshes on occasion. Sometimes you'll click on something that causes the Gmail screen to refresh. So like I just said, it's not 100% single page application, but for the most part, once you're in the Gmail screen, anything that you click, whether it's in the side folders or your mail, doesn't refresh the whole page. It just changes section of the view. And it does this in a much more simpler way than you think. It does this by changing state in a view model. So that view is designed to toggle div tags off and on, div tags that are appropriately positioned in certain parts of the screen, and it turns them off and on based on properties in the view, in the view model. And in its most basic way, that's all SPA really is. It's a single view that gets delivered by whatever the delivery platform is. In my case, it's NBC. I'm using NBC here just to deliver my HTML. And then the view model will turn flags off and on, and those flags are bound to things in the view, usually div tags through visibility. And turning these things off and on in the view model causes div tags to turn off and on in the view. And that gives the appearance of one page, of one larger application that's really driven by just one page. I'll show you an example of this. So there's a basic and a more complicated way of doing SPA. And I want to make sure you understand my personal opinion on this. And this is my opinion. One is not better than the other. I use both in an application. And just because this says basic, I'm going to teach you this, and I'm going to teach you this. But just because this says basic and easy doesn't mean that this is what you want to learn, but then you want to use this all the time. Because I don't personally. For small views, because what makes these two techniques different is really the size of the HTML that you're rendering. And if I'm developing applications, views that are going to be SPA views, meaning one view for multiple view modes, and it's a small enough page where I don't feel it's going to be too much of a drag on the resources and speed in delivering that entire page, I'm going to stick with this because it's much more easier to program as I'm sure you'll agree with me when you see it. But if I'm going to deliver a view whose subsections are really large, and there's a lot of HTML there, then maybe I don't want to deliver that all up front because it's going to slow things down a little bit. And that's when I would use a technique like this. You're going to learn both of them. And we're going to do this without any external resources. There are other frameworks out there that I'll discuss briefly at the end of the session that help you do what I'm doing. But I'm doing this with just knockout, nothing else. This is all about technique. So basically with this basic and easy SPA here, all I'm going to do is that the view is going to deliver an initial layout, and I'm going to have diff tags to define the different modes of the view. I have one view that's going to flip between two different modes. One of them is a list mode, one of them is an edit mode. In a more complicated real-world situation, I'd have a bigger page and I'd have sections within that page that would turn off and on. Here I'm just turning the entire view into something else. So traditionally in NBC, if you want to have a list of something and then click on something in the list and show details for that in a totally different page, you'd go back out to the server to deliver a new view. But I'm doing this with only one view. I'm just switching, toggling back and forth into what this view looks like. Let me show you right, go right to the code instead of wasting your time with the slides. So let's go over here to the simple SPA. This is my, now notice all of my knockout views start out like this, because I'm using a layout page. So I have a script section where I deliver the script, there's my knockout view model, and then I have a KO apply section where I'm doing the binding. This is just because my layout page, this is basic NBC, this is why I like to use NBC for HTML and knockout delivery. Because here I can design my layout page with all my CSS and bootstrap and all that stuff. And then here is my render section KO apply and here's my render section scripts. So then I know exactly where I want to put the script declaration and I know exactly where I want to put the knockout binding. Notice it's inside the javas to jQuery function document ready. So now I come out here and now I know where this is going to go and where this is going to go. And then I got the rest of the page. Now take a look at this page. This is an SPA. This is the first and most simple SPA view that you'll see. Okay, it's basically, there's the page right there. There's the view. The view is just a div tag with two other div tags in there. Now this div tag is going to show a template called list template. And there's list template here. It's defined as a script tag type to HTML, which means this is going to be delivered by the browser, but it's not going to visually render. If I were to make this a div tag, then it would display. I don't want it to display. I just want it to have the HTML there and ready for me without actually displaying. So it's done as a script type equals text HTML. Now here is my list of people. This is very simple, very similar to the previous knockout example that I showed you. I have a list of people. The code in here looks the same as what you've seen before. There's the for each people and there's the first and last name. Then I got another script tag down here which shows person data using text boxes. So it's just a different view. I've drawn something differently. Traditionally in NBC you do this in two different views. I've done it in one view, but two different script sections. Everybody with me? Now this top part here, this is the main part of the view. This is where I define my layout. So if I had a complex layout where a panel goes here and another one here, maybe there's a big section down here, this is where it's all drawn. And all I'm doing is that I'm drawing that layout and the two panels that I'm interested in displaying at different points in time, I'm showing them as div tags and I'm pointing them using knockout template binding to that template. List template is right there and then edit template is the other one. The trick to making this an SPA is now the visibility of each one of these div bindings. So now this panel here, this first one, is only going to be visible when a property in my view model is set to list mode. If the property is not list mode, then this is going to return a false and this div tag is not going to display. Same thing as if the property is set to edit mode. If it's set to edit mode, then this one is going to display, this one is not. So basically by toggling this one property here between the value list mode and edit mode, these two div tags become visible or invisible. You understand how that works? That's SPA and I couldn't dumb it down any further in its most simplest form. And the next example is going to be just like this, but it's going to do it just a little differently. But this, believe it or not, is how Gmail works. What makes Gmail look more complex is its layout is more complicated, is more nicer and it's just more complicated looking. This is just two div panels on top of each other, one showing and one not. If I go over to the view model, you'll notice that the view model is pretty much the same. There's my model object, there's the load people that you saw, there's the person and people, there's the save. Now look what I'm doing. I have this edit person function. Look at the job of the edit person function. The job of the edit person function is to simply set the person variable in knockout, the knockout observable, to a person that comes in and then change the view mode. Knockout properties, the observable properties I spoke to you about earlier, they're in reality, they're functions, they're not properties. We call them observable properties, but they're actually knockout functions because they're created like this with KO observable. So in order to set their value, you don't say self.person equals, because you'd be overwriting what that observable is. You say self person and then in parentheses it's value. In this case self view mode and in parentheses it's value. So here I'm just toggling the view mode to edit mode. Here in the save function, I'm toggling the view mode back to list mode. Now what's causing edit mode and save, edit person and save person to fire? Well, let's see. Okay, so here's my first part of the view, the first mode is that list, that table. There's the edit button that's right next to my first name and last name. So on every cell, on every row, I get an edit button and I'm calling edit person. And because the context of this binding, this is important, the context of this binding is inside the for each loop, all of this here is going to apply to each element in people. And that includes a function. So any function that I call, in this case edit person, is going to receive that person here. So each line is going to have an edit person link and each one is going to send that person to there, to the view model. And when the view model receives that person, it's simply going to set it in this observable property. Hopefully something is using it. Let's see if something is using it. So down here, in this other template, edit template, I have with person. So now by me clicking edit, in the view model, change the value of the person object. By changing that value, all of this changes. And because I'm also changing that view mode property, this up here will toggle. So I did two things. I clicked on edit and by clicking edit, I changed the person object. By changing the person object, the first thing that took place is anything bound to the person object changes. So if the screen is bound to the person object in some way or form, it's going to reflect that. But that something may or may not be visible. Just because this changed doesn't mean it's currently visible. What made it visible is that second thing that I did by changing view mode and by changing view mode to the word edit mode, I now turned this diff tag on and I turned this one off. And watch what the effects of this is. So now by clicking on my name here, it flips the diff panel. And now the table is invisible. It's still there, but it's invisible. And by setting that person object, I get my name in here. By clicking save, all I'm doing with save was setting view mode back to list person. So by setting view mode back, it's just turning this panel off and turning this one on. And if I click on Michelle, for example, there she is. And because all of this is done with binding, watch this. I'm going to change to the English version of my name, Michael. And this should bind to the person object. I don't know if that's going to work or not. Let me see. Yeah, there we go. Because it's bound automatically and that person object is one of the elements of the people collection. It's all done through the magic of binding. Automatically, when I toggle back to the list mode, there's my name. It's been updated. Click edit again. Click save. And now I'm back to Miguel. So two things I'm doing here at the same time. I'm affecting the underlying properties in the view model. So things on the screen get properly updated. And I'm using a very special toggle property called view mode to switch my panels off and on. The rest of SPA is that right there taken to another level. It's turning panels off and on. Maybe some panels have other panels inside that get turned off and on. But the concept of it is exactly the same. Things can just get as complicated as you allow them to get. But the basis of HPA is nothing more than one view with a bunch of different panels spread out however you want to spread them out. And things in the view model changing to affect those panels visibility. That's all SPA is in its simplest form. With me. Pretty cool stuff. Lie to me. Just go like this. All right. Now, because this is very small HTML, I don't have a problem doing it like this. And most of the time I don't. So this is one of those things where you really have to weigh out the complexity of delivery versus the true impact on resources. Too many people spend way too much time thinking, no, no, I need to get that last nanosecond of speed. But in trying to obtain that extra nanosecond of speed, they're extending the ability to deliver their product by two weeks. And to me, that doesn't make sense. And when you're charging X amount of dollars per hour, it's not going to make sense to your customer either. But sometimes doing it like this, even if it means rendering the page in a blink of an eye longer than it would take if I do it the next way that I'm going to show you. To me, it's still worth doing it this way, simply because it's easy to code. And I can deliver a product really quickly. But there may be a time where these templates that you're looking at here are really, really big. And when I say really big, I mean maybe 10 or 12 pages of HTML or really, really complex. And maybe I don't, and maybe I have seven of them instead of just two, like you see right here. So it's very, very possible that the page, the initial page, because the single page, the initial delivery can delay an extra one or two seconds. And you don't want that to impact the user. In which case, you may want the loading of this information to be dynamic. Go get it when I need it and only when I need it. And if I don't need it, don't ever go get it. As opposed to the example I showed you, where I go and get everything. And then I worry about toggling and visibility and hidden. And that's what the next example is going to be. I'm not going to bother going back to the slides. You guys mind? I'll just stay in the code. So look what this one is. Much more simpler page, right? This is the initial page. As a matter of fact, it looks exactly the same as the other one, except that as you can see, the script templates are missing. However, the main layout is still there. But there's one addition, because now we got to mix a little jQuery in here. So I identified the divs. The previous one didn't have the divs identified. Here I'm identifying list mode section, edit mode section. But I'm not binding to any template. I'm just saying show it based on the view mode property and identify it with this, because I'm going to need that identifier. So now let's go over to the view model, because the view model is a little more complex. So look what the view model is doing here. So when I go to... Nope, that's not it. Hang on. So when I load everything up, look what I'm doing here. I was just saying load people. But now I'm saying, okay, now change my view to list mode. Now, why do I go with this function called change view? Well, look what change view is doing. Change view is doing one of two things, depending on whether it's list mode or edit mode. I'm going to call another helper function called load view. And now I'm going to obtain that template from a partial CHTML. So now what used to be in two script templates in a single view, I've actually offloaded to one control and another control. So two different HTML files, but they're partial HTMLs, because it's going to be the job of the view model to say, I want to take this partial HTML in the world of web forms we used to call this user controls, remember? I'm going to take this HTML snippet here and I want to load it into the list mode section, which is why I identified the divs. I want to take this one and load it into the edit mode section. So now that magic is done by the load view. And the load view is essentially going to go and get that HTML and loaded into the element that I've identified in that div tag, and then apply the binding of this view model. That's an important piece there. If you don't do that, you don't get the knockout binding to work. So you've got to take the same apply binding that I did to the main view and do an apply binding on that new element with this view model. That's why it says self. Now, the magic of this function is this right here, because what I've got to do is that I've got to take this and I have to load it up. And opening this as a data file, as a file, and saying just give me the text HTML and put it in there is not enough. You need to let NBC do its work. This may have some script in there, some razor script. This may have some JavaScript. It may have a whole bunch of stuff. So you don't want to load this up as a text file. You want to render it like NBC would render it when it's rendering a regular view. So that's why my view model is going out to Web API. And it's returning from Web API that view in a very special way, because it's not just going to open the file and get me the HTML. It's going to go to Web API to get partial method right here. There's the name of the view and it's going to return it as a partial view. By doing this line of code, I'm letting NBC render that view. So if there's any JavaScript in there, there's any razor scripting, it'll all get evaluated and rendered by the NBC engine. So it's more than just doing system.file.io or system.io file and opening it up as a text file and bringing that text file back and sticking it in the inner HTML. I need to bring back the resulting HTML of what it would take to properly render this view. Does that make sense? And once I have that result, I'll have it here. So this is not going to be the same HTML that you're seeing right here. It's going to be the result of rendering this and evaluating anything that needs to be evaluated. And then, then and only then, will I take that result and stick it into that Div tag. And by doing that, I've been able to separate out the main layout of that single-page application from all of its different mode layouts. And the end result is kind of the same. Is this thing still running? Yeah. Now, it's not going to look any different. It works exactly the same. But it's done a little differently because right now, when I first ran this, the only thing that loaded was the main layout page and that one view that I'm displaying, the list. And I never, ever press edit. The other user control, the other CHHTML file is never brought in. So that HTML was never rendered. And if that's a really, really large amount of HTML, it could save you on some resources. So both techniques are important. Don't jump right to this technique because you want everything to be at the nanosecond level because you may not need it. And if you don't need it, it's a lot easier to program the last one. But I felt it was important enough to give you both techniques. Yes. You call me sir, sir's my father, man. I'm an American. You call me dude. What can I do for you? This scenario is also a useful offline scenario. When the user can use your application in offline mode, then you will use the first one, right? That's exactly right. If you're offline, you can't go to the server. Then you would have to use the first one. Yeah, absolutely. Yeah. Way to think ahead. Absolutely. Yeah, wouldn't it suck if you use the second one for everything and then you have to get on an airplane? Exactly. It doesn't work. Yeah, because you're using WebAPI to go get something, which means you have to be accessible in the server. So, yeah, definitely a good point. All right. Now, everybody having fun? All of this is kind of cool. Now, imagine yourself writing this great application that does SPA and I run it and I switch this to another view and then I switch this back and then I switch this. And I'm like, ah, you know what? I changed my mind. Let me go back to the list. Let me hit the back button and poof, I'm back here again. And that sucks. And you're going to get that. It's important. I don't want to leave you without this. And I'm not going to spend a whole lot of time doing browser history because I do an entire talk on push state, on browser state. But it is important and I gave you some good samples for you to look at the code. You're going to get a lot out of my code. I take a lot of pride in my demos. When you deliver a view through NBC from the server to the client, at that point in time, NBC or the Web will actually push the state of the browser onto the browser history. If you're doing everything in the browser only and you don't go back out to the server like I'm doing here, right here, I didn't go to the server. I didn't go to the server. This is all done with the magic of JavaScript. I've stayed in the browser. The only piece of history the browser has right now is the initial page that it got to. Which means what's the page before that? The menu page, right? So the minute I hit the back button, what happens? You go right out there. And this doesn't give you a polished application. What it does give you is a really pissed off user. Because the user is going to change a lot of stuff and they're going to press this and the screen is going to change. They're going to change more stuff and they're going to say, oh, shit, I messed up. And they're going to hit the back button and they're going to go all the way back. And that's going to make a really, really angry user. Sometimes I like to make users angry. It keeps them on their toes. But most, a lot of times, the user is paying the check too. So you don't want that. So in HTML5, you have the ability to actually push state to the browser itself. Which means you're effectively fooling the browser into thinking that something has changed in the URL. And it needs to push something onto its history. Browser history is just a stack. And like any stack, you're going to push something into it. You're going to pop something from it. The problem is that by default, the only thing that pushes onto the browser history stack is when a new page renders from the server to the browser. And when you back button, then it pops from the stack. What we can do today with HTML5 is that we can manually push, using JavaScript, to the browser history stack, to make the browser think that there's more things in its stack. And then pressing the back button will pop something from the stack. And we need to be able to tap into an event that tells us what's just been popped and what does the stack look like now. And now the hard part is that it's up to me to manually change my view based on the current item on the browser stack. It sounds complicated and I wish I had more time to get into a lot of detail, but I'm going to show it to you anyway. So here's the history tracking view. It looks exactly the same as the previous example, so we're not going to spend a lot of time in this view. The view model is where it's a little different. What I've done with the view model, all this is the same. Load people, save person, all of this is the same. What I've done is that I am subscribing. This is a knockout feature. You can subscribe to a property. Remember that view mode property? In knockout, you can actually write a subscription so that anytime anything changes the view mode property, this gets fired. Think of this as an event. So now anytime that anything in my knockout view model changes the view mode property, I know that the view is going to change. So this is where I want to affect the browser history. So I wrote some code here that cases on what my mode is. Is it list mode or is it edit mode? And then what I'm doing without getting into too much detail, because I still have one more thing I need to show you before you leave, I'm using a helper class that's down here at the bottom that I wrote. I'm going to let you play with the code. And what I'm doing is that I'm actually pushing onto the browser stack the code name list mode. This can be anything, but it's from my own sanity. I made it the same as this. I'm pushing the code name list mode or edit mode with whatever the URL I want it to look like on the browser. Now notice in this example, the next example is going to be different. In this example, the URL is the same. Home history tracking. What's important here is this here. Because now what happens is that I'm also subscribing to the Windows on pop state function. This is what's going to get fired when you user presses the back button. And what's going to come into here, our state is the code. And notice what I'm doing. I'm doing change of the view. So anytime that I change the view, I'm pushing whatever that view is, list mode or edit mode onto the browser stack. And anytime the user presses the back button, whatever that last push was gets changed here. And it's this change view that causes my actual view to change. The browser doesn't keep track of that memory. It doesn't know it because it was all done with JavaScript. The browser just keeps track of this or this. List mode, edit mode, list mode, edit mode, list mode, edit mode. And then you hit the back button, it goes back to edit mode. Hit it again, back to list mode. Hit it again, back to edit mode. And it's me that's actually causing the view to change. This works seamlessly when the next problem is an actual push from a blog page. Well, that's going to be a totally different view. And the process is going to start all over again. It won't be your function. No, but my stuff still stays in the browser stack. So if you go now to a different view and you start changing that, and then you back your way back to this one, all this is still in the browser stack. So it'll still work just fine. So the appearance of it is actually very cool because watch what happens now. I'm going to press edit on Brian. This is all with JavaScript. Hit save, edit on Carl. Hit save. Now, the back button goes back to Carl. Look at the URL. Stays history tracking. Now go back to here. Now you should go back to Brian, right? I would need to do more work to keep track of the actual person. I didn't do that work. But you saw that the view actually gets tracked. Now the URL didn't change. Why did the URL not change? Because there's only one URL. And that's this one right here. That's what the next example is. I wish they would have made these things an hour and 15 minutes. Because I got three minutes to show you this last piece here. When is the next talk? Is it a 10.15? A 10.20? If I take like five minutes, anybody going to get pissed off? All right. Nobody's going to give me a red card because I took an extra five minutes. Because this stuff's important. Now watch this one. I have this home controller here that's been driving everything. This home controller is going to drive another view called multi-sub-entry. The idea here is that now I'm going to give you a different URL. Because this is very, very common. Who uses GitHub here? So have you seen how cool GitHub is? GitHub does everything with SPA. So every time that you click on folders in GitHub, all it does is change that one section in there. But have you paid attention? Every time that the folder changes in GitHub, did you notice the URL changes? Which means you can actually target a specific folder structure in GitHub by going right to the URL. So what I have here is that I have, this is a little more complicated. I have a view called multi-subview entry. That's going to give me three different states. Step one, step two, step three. Now I've shown you SPA so far with a view that has two states, two modes. List view and edit mode. However, I haven't given you a way to use the URL to jump straight to one of those modes. I forced you to start at the beginning and then manipulate the mode using what I give you in the view. Here I'm going to do another thing. I'm going to let you go to here and I'm going to let you jump into step one, step two, or step three from the URL. And I do that with the help of an MBC model. So notice I'm returning a view. This is regular view rendering, but I'm rendering it using a model. The model has this initial state. You could also do initial ID if you needed to identify like an employee record or something like that. But let's just deal with state. So I have this one property called initial state here. Now look what initial state is doing. Mode one, mode two, mode three. Same view. Now take a look at this view. This gets really cool. So here this view is why I love using knockout with MBC because I mix these worlds together. So now I've delivered an MBC view with a model object that's got an initial state property. There's my model object, which means my initial state for those of you guys who's an MBC developer here? Okay, most people. So there's my model initial state. Now look what I'm doing. This is a server side property that I'm converting it to a JavaScript variable by filling it by saying var initial state equals. And then in quotes, I say razor syntax modeled out initial state. So now that's step one, step two, step three is inside a JavaScript object. Now I can send that into the view model right there because now it's up to the view model. Now look, the rest of this view is not complicated. It's exactly what you've seen in the past. There's my three divs. They're only going to be visible based on the content of view mode. Mode one, mode two, mode three. I'm going to show this or the other or the other. So now it's all about the view model, which now received this initial state. And if I go to the view model, which is right here, there's the initial state. And then if nothing came in, I'm going to set it to mode one. But if something came in, then I'm going to go to step one mode, step two mode, step three mode. And these functions are simply going to change the heading, a property called heading, and it's going to change the view mode. So heading and view mode are the three things that are changing, right? Let's go back out to the view and let's take a look at right here. There's heading and then view mode simply will toggle between step one template, two template, and three template. Now to polish this up, to make it a really, really clean application, look what I'm doing. I'm doing my old browser state thing. So now I'm subscribing to the view mode and based on the mode, I'm pushing to the browser. But look at the difference now. Excuse me. The difference is that now you're seeing three different URLs. And that was my choice because not only am I giving you, is it two different things? They look like they're same, but two different things. Here is where I'm giving you the ability to URL yourself right to a specific step. Here is where I'm pushing into the browser state with a different URL so it will change. I could have made this the same for all three and I would still allow you to target a specific step with the URL, but then the minute you start doing on the back button, this is what you're going to see in the browser. You want the two to match and you got to do this manually, unfortunately. Watch what the effect of this is. It's actually quite cool. Here's sub view one. Actually, let's start at two. Now, notice it says this is the second view and it gives me buttons for step one and step three and look at the URL. Step two, 102. That's 102 is that identifier, which is meaningless for our demo. Now, watch what I can do. I can jump right to step one by going to the URL. Watch this. Now I just jumped to step one. So now I have a way to actually get into, remember, all three steps, step one, two and three are all driven by the exact same view. They're just three different SPA modes of that single view, but now I can use the URL to jump right to each any one of them. And now I can go to step two. See the URL change. Step one, the URL change. Step three, the URL change. Now let's go to the back button and see what happens. Now I'm back to one. Now I'm back to two. Notice my URL is in sync on the browser bar. Now I'm back to three. Back to one. Back to two. And back to the menu. So I get a nice polished application. The user is getting pissed off and I still get a nice big check in the mail. Right? So guys, I hope this has been helpful. I think the best part of this is probably going to be if you download the code, I've tried to give you, I pride myself on my ability to write demos. So if I don't have time to show you something in the level of detail that you want to see it, I'm hoping that downloading the code gives you a really, really good kickoff point to write these things. This is very, very cool. In my opinion, the last line here is the key one. You'll never develop a conventional ASP.net MBC application again. Once I start using this stuff, knockouts become almost part of my regular stack. No matter what kind of site I'm writing, it's always going to be done this way. And since I'm coming from a WPF world, this just made sense. When I started doing knockout MVVM, it just felt right. This is the way I need to write applications. Concentrate on the view model, let the view refresh itself based on my state changing, which is the same way that I think when I do WPF. So now I don't have to think in two different ways and I have more time for scotch and cigars. So I hope you guys enjoyed yourselves. I got a session at the end of the day today on dependency injection on number seven, I think. So come back and see me and thanks for coming. Hope you had fun. Thank you. Thank you. Everybody needs to follow me on Twitter, okay? I don't have enough followers yet and that bitch from Jersey Shore, Snooki, she had like 90,000 followers. That pisses me off. Thanks, man, appreciate it.
 All right, is this thing, yeah, it's loud enough.  Okay. Good morning everybody. How do you say  good morning in Norwegian? That's exactly what I just said.  Say it again? Seriously, say, how do you say it?  More? Wow, pretty close.  I don't know any Norwegian whatsoever. How do we know how to say yes or no?  Which is probably a good thing. Thanks for coming in this morning.  We're going to talk about SPA with Knockout. Any Knockout users in here?  Has anybody heard of Knockout but not quite gotten there yet?  Looking forward to seeing maybe a little demo, a little primer?  Because I have one for you. I'm going to spend just a little time giving you a Knockout primer.  It's a great technology. If you haven't gotten involved in it, if you're doing MBC, or if you're doing any kind of web development,  you haven't gotten involved in any of the MBVM frameworks, you really owe it to yourself to look at them.  And hopefully I will inspire you to do so.  Because we only have an hour to spend together, so I want to leave you with just enough information  so you can leave and continue learning this stuff.  So my name is Miguel Castro. This is a special picture that I put together for you guys.  I don't use it anywhere else in the world except Norway.  My good friend Johnny over there sitting in the middle of the crowd  is the one responsible for giving me that helmet, which freaking almost broke my nose.  I don't know how the Vikings did it, but this thing weighs like 20 pounds.  And you put it on your head and as soon as you nod, it falls down and it hits the bridge of your nose and you break your nose.  So thanks Johnny, you bastard, you almost broke my nose.  But it was a wonderful gift. The only problem is it doesn't make it through airport security unless you put it inside your bag.  Because you can probably break right through the airplane cockpit with this thing.  You put it on your head and just crash right through.  So who's attended one of my talks at NBC before?  I'm going to go ahead and talk about it.  I'm going to talk about it before.  Alright, mostly new people. That's good. I like that.  Anybody ever see me in any other conference in the US?  In Florida, in Orlando. What the hell did I do in Orlando?  Oh yeah, VS Live. That's a good conference.  That's one of my regular ones. That's one of my favorite conferences. That and this.  I got to say that. NBC is one of my favorite conferences. I love Oslo.  Very helpful today.  So we're going to talk about knockout and SPA.  Primarily SPA. But I got to give you a little intro to what that is.  Because it's one of those terms that's not properly defined.  And I want to make sure you understand exactly what it is before you understand how to use it.  We're going to talk about NVVM first.  Just very briefly through a couple of slides. Then I'm going to spend probably about 15, just 15,  20 minutes tops giving a knockout primer to you guys.  Mainly because I anticipated that a lot of hands would go up when I asked a question who's not used  knockout before. This is an attractive subject. But unfortunately for me to jump right into what SPA is,  you have to have kind of a basic understanding and fundamentals of what knockout is.  So I'll be spending just a little bit of time on that.  And then we'll get into SPA and I have a couple of different techniques that I use for SPA.  Who's done any kind of SPA programming with knockout?  Or with anything else?  It's pretty cool. Once you start doing it, you don't want to do websites any other way.  It brings a level of richness that until recently we only had in desktop applications.  If you use WPF or Silverlight, you get really rich UIs. We couldn't do that easily in the web before.  And now we can.  There's one additional topic I want to throw in here at the end of the day and that's browser history.  Because when you're doing SPA, keeping track of browser history becomes very important.  So I'll get into more details on that and you'll understand what I mean later.  So basically what MBVM is, if you've never done it before, it's just a pattern.  It's an architectural pattern for separating UI logic from UI.  It is not the separation of business logic. That's a really, really bad definition.  And I see that definition too often where you read a book about what MBVM is  and it says MBVM is a pattern that separates the business logic from the UI logic.  That's bullshit. It's not. We've been doing layered applications  for a very long time where you have UI business and data tier. That's separating  business logic. MBVM takes the UI layer only and  it separates it into logical and physical design. So a  view model is essentially just a logical representation of the user  interface. All of the elements on the user interface that are physical  and all of the actions that a user interacts with, those are represented  logically in a view model through behaviors and properties.  It's at the heart of XAML programming. Who does any kind of XAML here  at all? Whether Silverlight WPF or Metro. Okay.  I still call it Metro. I like that term. Microsoft can sue me over it rather.  If you're not doing XAML, if you're doing XAML  without MBVM, in my opinion, you're doing it wrong. So you really owe it to yourself  to learn what that is. This until recently,  it's all about state-drivenness, meaning you change state in the view model  and then it reflects in the view through binding.  Those of you that raise your hands with XAML, you understand what this means. You know, you do  everything through binding and you change a little bit of state and poof, the UI just changes  magically. That's at the heart of what MBVM is, a state-driven development.  Until recently, this was not really possible on the web in  an easy way or a good way. The web for a very long  time has tried binding through different iterations  from old ASP to ASP10 and then ASP20. And every  iteration, it gets a little better, just a little bit. But it doesn't really  get all the way there. And with these JavaScript frameworks that  have surfaced over the past year and a half or so, it's gotten  there, in my opinion. A knockout is my favorite. It's the one that I like  to use. There are several on the market. There's another one out there you might have heard of called Angular.  AngularJS. There's one called Backbone. So there's several  frameworks out there and they're all very, very good. I just happen to like knockout because I like the way  it works. It's just a personal preference. It's like saying C sharp versus VB.  Alright, maybe no. Who does VB development  in here? There you go. Everybody just stare at this guy.  VB's great, man. I had a great  career with VB. Never want to do it again in my life.  So what knockout is, that knockout is what allows us to do MBVM type  development, which you're going to get a demo of in the web world.  I set the web world because it's not really the Microsoft  world. Knockout was developed by one person originally. A guy named Steve Sanderson.  Brilliant guy, works from Microsoft. And he wrote the framework before he came into Microsoft.  And he brought it with him and it became so successful. It was such a big  hit that Microsoft actually puts it into the NBC  templates now. So when you add a new NBC4 application to  your projects, to your solution, you will get the knockout libraries  automatically in there. There is another library that we're going to get pretty soon  automatically. It's called Bootstrap. Who's heard of Bootstrap?  Twitter Bootstrap. It's pretty cool, isn't it? I mean, it's just an easy way of getting  real professional looking web CSS  without a lot of work. Bootstrap's going to become part of the NBC project  template as well. So knockouts were written entirely in JavaScript  and it's got no dependencies on Microsoft. In fact, if you go to  knockoutjs.com, which is probably the best source that you can go to for knockout training,  that and the plural side courses, you'll see that it's not an  NBC site. It's nothing but HTML and JavaScript. So it has no  dependency. However, in my opinion, NBC is a great delivery platform for it.  NBC, the NBC framework becomes the deliverer of the  JavaScript and the HTML. And I don't think anything can deliver HTML much better.  than NBC when you start mixing all the C-sharp stuff that you can do with it.  So that's what I'm going to be using to deliver my knockout and my HTML.  Knockout works with data dash tags. This is how we do our binding.  You'll see that in a second. And it's easy to install because it's available as a new get package.  And like I said, it's already there when you add a new NBC 4 app.  Maybe not up to date, so you have to go to new get and do an update. But it's very, very  easy to install. It works through this concept of observables.  And this is what MVVM is about. It's about observability.  In the XAML world, for those of you that are XAML developers, you've heard of  property change notification. That's the same thing as what I say, observables.  It's all about this concept of the view of  subscribing to the view model and saying, let me know when something has changed.  So when a property changes in the view model, the view  automatically updates. That's the beauty of MVVM is that we're not directly  interacting with the view. We're just changing state in the view model and acting  upon actions in the view model. And automatically the view changes.  And if done right, it actually can be a very, very  elegant way of developing. I'm going to jump right to the  knockout demo, so I don't waste a lot of time.  But you're going to see that it's not as difficult as a lot of people think. I do a whole  hour session on just knockout. Unfortunately, it wasn't chosen  for this conference. So let me, I already have a pre-canned  one, and that's what I'm going to bring up.  So how's this font for people in the back? Should I make it bigger?  Yes? Okay. You want bigger, you got bigger here.  Is that better?  Anybody need bigger than that? Okay.  Can everybody see me standing on stage? Just want to make sure.  Alright, so this is a sample knockout view model. Now without getting,  when I do my whole hour on knockout, I get into the step by step. And I build it from scratch  and I build small ones first, or just a couple of properties, then I make it bigger and bigger.  I just want to head to a full blown one here so you can see that I'm  just going to head to a full blown one here so you can just get the idea, because this is nothing but a little  50 minute primer that we're going to do. But this is essentially just a  JavaScript function. Everything in knockout is a JavaScript function starting  with the top, which is the view model. So this is my view model here, it's just a JavaScript function.  And then I'm declaring the properties. In knockout, when you create a view model  is just like in XAML when you create a view model, you create a  class that has properties in it. And that property becomes your state, because that's what the view  is going to bind to. This is no different. It's an exact correlation.  So I basically just have a couple of properties here, one called person  and one called people. And notice person is just a single object.  And it's an object of this other  type here, called person model. So it's no  different than creating a property that's a type person model class, if you were doing this  in C sharp. This is just a JavaScript version of this. And then you got this other object  here called people, which is an array. This is in C sharp, this would be the  equivalent of creating an observable collection. Everybody know what an observable collection is  in C sharp? It's what we use in MBVM. So then the rest  are all just functions. And what I have here, for example, is that I have a function called  load people. All load people is doing is going out to a web API call  and getting information. This is how you would get data in  knockout, because the whole idea is that the view is going to ask the view model  to do something. In my case, it's going to ask the view model to load some people. So  whenever the view calls this function, I'm going to actually make  a rest call to a web API. And  without getting into any kind of web API details here, this is just  a web API controller. There it is right there. It's called data. And it's got a method  in there called get where I'm building my list. Obviously in the real world, this would all come  from a database. I cheated it. I just created a list of some developer friends  that I know. And I bring that back. So  there's my API slash data, which is  going to here.  And I bring back that result. And then this is the  interesting part. Notice what I'm doing. In knockout, what I'm doing is that I'm taking the result. Now  this is a regular API call that returns JSON. As simple  as that. This is just an Ajax call. This here  has nothing to do with a knockout. Anybody recognize what this is?  It's jQuery. It's a standard jQuery call. If you don't want to use jQuery, if you have another library that you use to make Ajax calls,  by all means, use that instead. All I'm doing is mixing libraries here. So I'm making an Ajax call, and then I'm getting the  JSON result back. And all I'm doing here is that I'm telling knockout, turn that  JSON result into the array  self people that you saw that I declared up here. Because  it's now creating a bunch of observables. This coyomapping here  is a knockout plugin that turns JSON result  into an observable array. Now that's all I'm doing  is I'm creating this observable. But the whole idea of  MVVM is that as soon as we change something in the state, if there's  anything in the view that's bound to that, it's going to reflect right away.  So just the act of me creating this variable  without doing anything to it, is going to immediately do something. Because if I go over to my view,  in my view, notice I'm loading in my view model  JS here, and now I'm binding it here. This is the equivalent  of your, and I'm making comparisons to XAML because I had quite a few XAML people here, and it's kind of the world that I come from. I come from the XAML  world originally. So what this code is doing is it's  instantiating the view model and binding it to the view.  In XAML, this would be the equivalent of taking the data context property and binding it  to the copy of the view model. Everybody know what I'm talking about there when I say data context?  If you're a C sharp person, that's exactly what this is. I'm  targeting the KO demo, which is this right here. So this is like  saying give me the div data context and binding it to that view model.  Now what I've done here, and this is where it starts to get really cool,  is that that entire view model with all its properties and all its actions,  all its functions, is now available for binding from this  level and down. Just like a visual  tree in XAML applications. So now remember the property  that I just changed? I changed the property called people, right?  By me filling up this property, if anything here  was listening to that, it will automatically reflect.  And as you can see, I have a div tag  where I'm data bound here.  Where's the, nope, that's not the one, sorry, right here.  I have a table, very simple table,  where the body of the table is data bound to the people.  And I'm just doing a for each. So now inside,  I can say, bind this TD to the first name property, this TD to the  last name property. And that's under the assumption  that the people collection has objects in it that have a first  name and last name property. Which in my case they do, because the JSON  that is being resulted here is  being built by a C sharp object called person model, which has first name and  last name. Which means when that JSON comes back to right here,  it's going to be JSON representation of an array of first  name and last name objects. So as soon as I turn that into a knockout  observable array with this line of code right here,  now the people collection is going to have objects that have first name and last name.  So all I have to do now is just  write my UI as simple as possible. Notice there's no code in here that says  go get it, go load the people, build the list. I'm just showing you  what the table looks like. And for, in the table I have  a t body section with only one row. And all this is saying  is that this is all going to be duplicated for however many  people there are in that array. And any change that I make to the  people, whether I change a person inside of it or add a  new person to the array or delete one, is going to automatically  refresh this. Because the framework, the knockout framework is overseeing this.  There's no code here that shows you that. There's no code that shows you that as soon  as a new person is added or a person is deleted, redraw  this. The knockout framework does that automatically. This is exactly  the same as is done in XAML. If you've done XAML binding before, you know that this is how it works. You do a  list box in XAML, you define in the list box what one list item is going to  look like. Which is what this is. One list item. And now you just  rely on the view model changing. And as soon as the view model changes, whether it goes up  or down, this is going to reflect automatically.  Back to my view model.  This load people. Notice these are all functions.  But then at the bottom here, I'm calling load people. So as soon as  the view model is instantiated, it defines all this.  And then it sees this and it calls it. So it's going to go ahead and load  the people. So just by  loading this object right here, let me show you what I get.  Let me show you what I get.  At the risk of sounding  completely geeky, knockout with  NBC has not only made, to me, it's made getting back into the Web World  a lot easier, but it's made it a whole lot of fun. It's actually fun to write what the hell  it is. And then it's going to be a lot easier.  And then it's going to be a lot easier. And then it's going to be a lot easier.  It's actually fun to write, what the hell is going on here?  subsid...  It's made it fun to write Web applications  again.  env...  audio  audio  Okay. Local host is not responding.  Recover web page. Look at that.  Leave it to Microsoft to go out to the Visual Studio to completely screw up what I'm in front of an audience.  Huh? I should. Look at that. What the heck? This was working last night. You know what you got to do to a Windows program?  Look, now it's not even closing. I think it's, it's a, I use crap. You know what you got to do to a Windows system to get it to mess up and start breaking shit on you?  Absolutely nothing. No, you don't have to do a damn thing. Just leave it alone.  Let's try Chrome. Alright, there we go. Good old Chrome, right? Jesus. Damn you, Microsoft.  Hey, there's an, this room's pretty full. There's an overflow room, right? So there's supposed to be people watching this?  Hey, I want to make sure that the overflow room can hear me. Can you guys just yell, hello, Miguel?  Chicken? There's no balls in the overflow room. Alright. So look what I did. As soon as I did that, there's that table right there.  You see how just drawing the HTML and drawing what a single item's going to look like and then binding it to the collection automatically repeated that part of the table however many times there were people.  Now what else is there in that collection? Well, what I want this demo to do is I want it to be able to add new people and delete people from that collection.  Well, this is the whole beauty of MBVM is that you don't think in terms of the view, you think in terms of the view model.  So now that we have this logical representation of the view and forget about what the physical view looks like.  Okay, the logical representation is a list of people. But now I want to be able to manipulate that list. So I don't have to think about how would I redraw that table in case I add a person?  Or where would I add it? Or how would I remove a person? Forget about that. I just need to work with the collection, which makes it a lot easier because I think in logical terms only.  I need to insert an item into the collection. I need to delete an item from the collection. And that's what these functions here do, add person.  All I'm doing is that I'm creating a new person object that's coming from, and I'm not going to describe this now because it's getting into more knockout information that I'm ready to give you today.  But a new person object is coming to this function and I'm taking that person object and I'm pushing it into the people collection. That's all I'm doing.  Notice here, you don't see me manipulate the UI. You just see me manipulate that one collection. I'm inserting a new person into the people. Down here for delete, I'm removing that person from the people.  All I'm doing is manipulating that collection. Now, this add person and delete person, these are actions. And in MVVM, you're not only buying to state properties, but you also buying to behavior.  So your TDs and your allies and your spans and all that stuff can bind to property so they can physically display something.  But your action elements like links or buttons can bind to behavior functions like add person or delete person.  So if I go back to my HTML, you'll notice that up here, I have a text box that's bound to a property called first name of an object called person.  And remember up here, I had an object called person and person is a type person model which has first name and last name.  So person is something that has first name and last name. So here I'm saying with person, bind the text box to first name. This with, this is just so I don't have to say person.firstname and person.lastname. That's all it is.  So I say with person, bind the text box and now that the text boxes are filled and they're bound to properties, anything that I type into the text box will automatically done for you by the knockout framework update these properties.  So now that person object in the view model has names of people I typed into the text boxes. Now look at this button. This button is going to be bound to the add person function.  So when I press the button, it's going to go to the add person function and because the button is inside the width, that's why the add person function receives that person here.  And that's how I'm able to take the contents of the text box and add them to the collection. So by typing something into the text box, I automatically will get that into here and then I can just add it to the collection.  And remember, the second that I added to the collection with no additional work on my part, the second I added to the collection, I should see it reflect here because this table is bound to that collection.  So as soon as the collection changes, the view will automatically receive a message saying something that you're bound to has just changed. Please refresh yourself.  Whether it goes, it changes to get bigger or changes to get smaller. And here, that table had a link next to each person that goes to the delete person.  And remember, delete person is removing it from the collection. So the act of removing the person from the collection will automatically refresh this because I am affecting the collection that the view is bound to.  Because it is observable. So with a very, very clean solution, no additional work on my part, look what can happen here. So I'll use my buddy Johnny back there. Where is Johnny? There he is.  So I'm putting Johnny Beckham's name in here and as soon as I press add, you should see it added to the table. And there it is with no additional work.  Now I'm going to delete Carl Franklin because he pissed me off the other day. And you can see that's gone. Now I'm deleting Richard. Now I can just add something else.  And there's that something else. Now I can delete it. All I'm doing is manipulating the collection. The fact that the view is bound to the collection, it grows and shrinks dynamically without you doing any additional work.  Tell me that's not like the cleanest little web page you've ever seen. It does complex stuff, but does it in a really, really clean fashion. Just take a step back and remove the knockout framework or anything you know about MBVM from this.  And just picture how difficult it would be to do something like that. In traditional terms. Eating with using jQuery. You can do it with jQuery. And for those jQuery fanatics in the audience, you're probably saying, of course I can do it with jQuery. Yes, you can.  But it's still not as clean as doing it like this because you'll have a lot of jQuery embedded code in your view. So things get more complex there.  All right, that's my knockout primer. Any questions? Does it inspire you to go out and learn some knockout now? Because it's actually very, very cool. I never want to create an application without it again. I really don't. Somebody had a question? Yes.  How are you? How would you, if you have the, you need to find a view or just finding other views based on view of can you bind CSS classes?  Absolutely. Absolutely. You can bind a whole lot. I've only touched the surface of knockout because I don't have a lot of time. But I can bind any, any, knockout has some default bindings. Like the value binding, the text binding.  But there's also a CSS binding. There's an HTML binding where it changes the whole inner HTML of that tag. So you can manipulate HTML in the view model and set it to a property and then have the HTML binding bind to that property.  And now it changes the entire thing. This is what you would do in jQuery with inner HTML. So it's got all sorts of bindings. There's also a binding called ATTR attribute.  So for any, any HTML attribute that doesn't have a built in knockout binding, you can use ATTR. So it's incredibly powerful. I really encourage you to go to either knockout.js, which will give you a nice little intro, but John Papa has a great course on plural site.  Who's got plural site subscriptions here? All right. Those of you that didn't raise your hands, go down to the plural site booth and get a free month subscription. Definitely. I need the money.  Actually, I'm working on a plural site course. It'll be out on July 31st. Yes, please go ahead.  Unless I'm preempting your presentation, when you're combining this with ASP.NET MBC, are you just using the Web API there? Or are you using?  I'm using Web API just for my Ajax calls, just to go out and get data. That's the only place that I'm using Web API here.  Is that what you would use from MBC? You would just program the rest just using knockout in a single view?  It doesn't have to be a single view. This is what I'm going to get into now. You are preempting the question a little bit.  So this gentleman is segwayed nicely into what SPA is, because what I just showed you is a view that delivers something that then changes dynamically.  It can be considered an SPA. What an SPA is, is short for single page application. And it's a real, real misuse of naming here.  A misuse of nomenclature, because most people tend to think when you read about SPA, it's like, oh, wow, so now my whole application is going to be one view.  In reality, that's not feasible, nor is it really easy to program. What SPA really is, it's about breaking your application down into sections.  And each section being SPA driven. SPA is about the way we program MBVM with XAML, where we have one view, one window, that then changes the way it looks.  But it doesn't mean you're going to have only one window in your whole application.  My use of SPA is what I think is a more realistic and a much more manageable approach, is where I have separate views for each section of my site.  So I may have a site that does e-commerce. So that site has a product catalog section, and it has a customer information section, it has a billing section,  a bunch of different sites, other sections just like Amazon.com does. And each one of those delivers one view, and then uses knockout in the way that I'm going to teach you now to flip and switch the way that view looks.  And that's what gives you the appearance of what SPA is, where you have one view, but instead of having that view refresh itself to the server to change the way it looks, it does that dynamically with knockout.  Some people take this to the extreme, and they do the whole application like this, with one view and one view only. They get one page, one CSHTML page that delivers the whole application, and then the whole thing is done dynamically by knockout.  Yes, you can do that, but it can get really, really complicated. I don't know if you want to put that kind of time into it. I certainly don't.  So I SPA sections of my site, not the entire site. A good example of what SPA is out in the real world is Gmail.  So if you use Gmail, you've seen a single page application in action, because Gmail refreshes on occasion.  Sometimes you'll click on something that causes the Gmail screen to refresh.  So like I just said, it's not 100% single page application, but for the most part, once you're in the Gmail screen, anything that you click, whether it's in the side folders or your mail, doesn't refresh the whole page.  It just changes section of the view. And it does this in a much more simpler way than you think. It does this by changing state in a view model.  So that view is designed to toggle div tags off and on, div tags that are appropriately positioned in certain parts of the screen, and it turns them off and on based on properties in the view, in the view model.  And in its most basic way, that's all SPA really is. It's a single view that gets delivered by whatever the delivery platform is.  In my case, it's NBC. I'm using NBC here just to deliver my HTML. And then the view model will turn flags off and on, and those flags are bound to things in the view, usually div tags through visibility.  And turning these things off and on in the view model causes div tags to turn off and on in the view. And that gives the appearance of one page, of one larger application that's really driven by just one page.  I'll show you an example of this. So there's a basic and a more complicated way of doing SPA. And I want to make sure you understand my personal opinion on this.  And this is my opinion. One is not better than the other. I use both in an application. And just because this says basic, I'm going to teach you this, and I'm going to teach you this.  But just because this says basic and easy doesn't mean that this is what you want to learn, but then you want to use this all the time. Because I don't personally.  For small views, because what makes these two techniques different is really the size of the HTML that you're rendering.  And if I'm developing applications, views that are going to be SPA views, meaning one view for multiple view modes,  and it's a small enough page where I don't feel it's going to be too much of a drag on the resources and speed in delivering that entire page,  I'm going to stick with this because it's much more easier to program as I'm sure you'll agree with me when you see it.  But if I'm going to deliver a view whose subsections are really large, and there's a lot of HTML there,  then maybe I don't want to deliver that all up front because it's going to slow things down a little bit.  And that's when I would use a technique like this. You're going to learn both of them.  And we're going to do this without any external resources.  There are other frameworks out there that I'll discuss briefly at the end of the session that help you do what I'm doing.  But I'm doing this with just knockout, nothing else. This is all about technique.  So basically with this basic and easy SPA here, all I'm going to do is that the view is going to deliver an initial layout,  and I'm going to have diff tags to define the different modes of the view.  I have one view that's going to flip between two different modes.  One of them is a list mode, one of them is an edit mode.  In a more complicated real-world situation, I'd have a bigger page and I'd have sections within that page that would turn off and on.  Here I'm just turning the entire view into something else.  So traditionally in NBC, if you want to have a list of something and then click on something in the list  and show details for that in a totally different page, you'd go back out to the server to deliver a new view.  But I'm doing this with only one view.  I'm just switching, toggling back and forth into what this view looks like.  Let me show you right, go right to the code instead of wasting your time with the slides.  So let's go over here to the simple SPA.  This is my, now notice all of my knockout views start out like this, because I'm using a layout page.  So I have a script section where I deliver the script, there's my knockout view model, and then I have a KO apply section where I'm doing the binding.  This is just because my layout page, this is basic NBC, this is why I like to use NBC for HTML and knockout delivery.  Because here I can design my layout page with all my CSS and bootstrap and all that stuff.  And then here is my render section KO apply and here's my render section scripts.  So then I know exactly where I want to put the script declaration and I know exactly where I want to put the knockout binding.  Notice it's inside the javas to jQuery function document ready.  So now I come out here and now I know where this is going to go and where this is going to go.  And then I got the rest of the page. Now take a look at this page.  This is an SPA. This is the first and most simple SPA view that you'll see.  Okay, it's basically, there's the page right there. There's the view.  The view is just a div tag with two other div tags in there.  Now this div tag is going to show a template called list template.  And there's list template here. It's defined as a script tag type to HTML, which means this is going to be delivered by the browser,  but it's not going to visually render. If I were to make this a div tag, then it would display.  I don't want it to display. I just want it to have the HTML there and ready for me without actually displaying.  So it's done as a script type equals text HTML.  Now here is my list of people. This is very simple, very similar to the previous knockout example that I showed you.  I have a list of people. The code in here looks the same as what you've seen before.  There's the for each people and there's the first and last name.  Then I got another script tag down here which shows person data using text boxes.  So it's just a different view. I've drawn something differently.  Traditionally in NBC you do this in two different views.  I've done it in one view, but two different script sections.  Everybody with me?  Now this top part here, this is the main part of the view.  This is where I define my layout.  So if I had a complex layout where a panel goes here and another one here,  maybe there's a big section down here, this is where it's all drawn.  And all I'm doing is that I'm drawing that layout and the two panels that I'm interested in displaying at different points in time,  I'm showing them as div tags and I'm pointing them using knockout template binding to that template.  List template is right there and then edit template is the other one.  The trick to making this an SPA is now the visibility of each one of these div bindings.  So now this panel here, this first one, is only going to be visible when a property in my view model is set to list mode.  If the property is not list mode, then this is going to return a false and this div tag is not going to display.  Same thing as if the property is set to edit mode.  If it's set to edit mode, then this one is going to display, this one is not.  So basically by toggling this one property here between the value list mode and edit mode,  these two div tags become visible or invisible.  You understand how that works?  That's SPA and I couldn't dumb it down any further in its most simplest form.  And the next example is going to be just like this, but it's going to do it just a little differently.  But this, believe it or not, is how Gmail works.  What makes Gmail look more complex is its layout is more complicated, is more nicer and it's just more complicated looking.  This is just two div panels on top of each other, one showing and one not.  If I go over to the view model, you'll notice that the view model is pretty much the same.  There's my model object, there's the load people that you saw, there's the person and people, there's the save.  Now look what I'm doing.  I have this edit person function.  Look at the job of the edit person function.  The job of the edit person function is to simply set the person variable in knockout, the knockout observable,  to a person that comes in and then change the view mode.  Knockout properties, the observable properties I spoke to you about earlier,  they're in reality, they're functions, they're not properties.  We call them observable properties, but they're actually knockout functions because they're created like this with KO observable.  So in order to set their value, you don't say self.person equals, because you'd be overwriting what that observable is.  You say self person and then in parentheses it's value.  In this case self view mode and in parentheses it's value.  So here I'm just toggling the view mode to edit mode.  Here in the save function, I'm toggling the view mode back to list mode.  Now what's causing edit mode and save, edit person and save person to fire?  Well, let's see.  Okay, so here's my first part of the view, the first mode is that list, that table.  There's the edit button that's right next to my first name and last name.  So on every cell, on every row, I get an edit button and I'm calling edit person.  And because the context of this binding, this is important, the context of this binding is inside the for each loop,  all of this here is going to apply to each element in people.  And that includes a function.  So any function that I call, in this case edit person, is going to receive that person here.  So each line is going to have an edit person link and each one is going to send that person to there, to the view model.  And when the view model receives that person, it's simply going to set it in this observable property.  Hopefully something is using it.  Let's see if something is using it.  So down here, in this other template, edit template, I have with person.  So now by me clicking edit, in the view model, change the value of the person object.  By changing that value, all of this changes.  And because I'm also changing that view mode property, this up here will toggle.  So I did two things.  I clicked on edit and by clicking edit, I changed the person object.  By changing the person object, the first thing that took place is anything bound to the person object changes.  So if the screen is bound to the person object in some way or form, it's going to reflect that.  But that something may or may not be visible.  Just because this changed doesn't mean it's currently visible.  What made it visible is that second thing that I did by changing view mode and by changing view mode to the word edit mode,  I now turned this diff tag on and I turned this one off.  And watch what the effects of this is.  So now by clicking on my name here, it flips the diff panel.  And now the table is invisible.  It's still there, but it's invisible.  And by setting that person object, I get my name in here.  By clicking save, all I'm doing with save was setting view mode back to list person.  So by setting view mode back, it's just turning this panel off and turning this one on.  And if I click on Michelle, for example, there she is.  And because all of this is done with binding, watch this.  I'm going to change to the English version of my name, Michael.  And this should bind to the person object.  I don't know if that's going to work or not. Let me see.  Yeah, there we go.  Because it's bound automatically and that person object is one of the elements of the people collection.  It's all done through the magic of binding.  Automatically, when I toggle back to the list mode, there's my name.  It's been updated.  Click edit again.  Click save.  And now I'm back to Miguel.  So two things I'm doing here at the same time.  I'm affecting the underlying properties in the view model.  So things on the screen get properly updated.  And I'm using a very special toggle property called view mode to switch my panels off and on.  The rest of SPA is that right there taken to another level.  It's turning panels off and on.  Maybe some panels have other panels inside that get turned off and on.  But the concept of it is exactly the same.  Things can just get as complicated as you allow them to get.  But the basis of HPA is nothing more than one view with a bunch of different panels  spread out however you want to spread them out.  And things in the view model changing to affect those panels visibility.  That's all SPA is in its simplest form.  With me.  Pretty cool stuff.  Lie to me.  Just go like this.  All right.  Now, because this is very small HTML, I don't have a problem doing it like this.  And most of the time I don't.  So this is one of those things where you really have to weigh out the complexity of delivery  versus the true impact on resources.  Too many people spend way too much time thinking, no, no, I need to get that last nanosecond of speed.  But in trying to obtain that extra nanosecond of speed, they're extending the ability to deliver their product by two weeks.  And to me, that doesn't make sense.  And when you're charging X amount of dollars per hour, it's not going to make sense to your customer either.  But sometimes doing it like this, even if it means rendering the page in a blink of an eye longer than it would take if I do it the next way that I'm going to show you.  To me, it's still worth doing it this way, simply because it's easy to code.  And I can deliver a product really quickly.  But there may be a time where these templates that you're looking at here are really, really big.  And when I say really big, I mean maybe 10 or 12 pages of HTML or really, really complex.  And maybe I don't, and maybe I have seven of them instead of just two, like you see right here.  So it's very, very possible that the page, the initial page, because the single page, the initial delivery can delay an extra one or two seconds.  And you don't want that to impact the user.  In which case, you may want the loading of this information to be dynamic.  Go get it when I need it and only when I need it. And if I don't need it, don't ever go get it.  As opposed to the example I showed you, where I go and get everything.  And then I worry about toggling and visibility and hidden.  And that's what the next example is going to be.  I'm not going to bother going back to the slides. You guys mind?  I'll just stay in the code.  So look what this one is.  Much more simpler page, right?  This is the initial page.  As a matter of fact, it looks exactly the same as the other one, except that as you can see, the script templates are missing.  However, the main layout is still there.  But there's one addition, because now we got to mix a little jQuery in here.  So I identified the divs.  The previous one didn't have the divs identified.  Here I'm identifying list mode section, edit mode section.  But I'm not binding to any template.  I'm just saying show it based on the view mode property  and identify it with this, because I'm going to need that identifier.  So now let's go over to the view model, because the view model is a little more complex.  So look what the view model is doing here.  So when I go to...  Nope, that's not it. Hang on.  So when I load everything up, look what I'm doing here.  I was just saying load people.  But now I'm saying, okay, now change my view to list mode.  Now, why do I go with this function called change view?  Well, look what change view is doing.  Change view is doing one of two things, depending on whether it's list mode or edit mode.  I'm going to call another helper function called load view.  And now I'm going to obtain that template from a partial CHTML.  So now what used to be in two script templates in a single view,  I've actually offloaded to one control and another control.  So two different HTML files, but they're partial HTMLs,  because it's going to be the job of the view model to say,  I want to take this partial HTML in the world of web forms we used to call this user controls, remember?  I'm going to take this HTML snippet here and I want to load it into the list mode section,  which is why I identified the divs.  I want to take this one and load it into the edit mode section.  So now that magic is done by the load view.  And the load view is essentially going to go and get that HTML and loaded into the element that I've identified in that div tag,  and then apply the binding of this view model.  That's an important piece there.  If you don't do that, you don't get the knockout binding to work.  So you've got to take the same apply binding that I did to the main view  and do an apply binding on that new element with this view model.  That's why it says self.  Now, the magic of this function is this right here,  because what I've got to do is that I've got to take this and I have to load it up.  And opening this as a data file, as a file,  and saying just give me the text HTML and put it in there is not enough.  You need to let NBC do its work.  This may have some script in there, some razor script.  This may have some JavaScript.  It may have a whole bunch of stuff.  So you don't want to load this up as a text file.  You want to render it like NBC would render it when it's rendering a regular view.  So that's why my view model is going out to Web API.  And it's returning from Web API that view in a very special way,  because it's not just going to open the file and get me the HTML.  It's going to go to Web API to get partial method right here.  There's the name of the view and it's going to return it as a partial view.  By doing this line of code, I'm letting NBC render that view.  So if there's any JavaScript in there, there's any razor scripting,  it'll all get evaluated and rendered by the NBC engine.  So it's more than just doing system.file.io or system.io file and opening it up as a text file  and bringing that text file back and sticking it in the inner HTML.  I need to bring back the resulting HTML of what it would take to properly render this view.  Does that make sense?  And once I have that result, I'll have it here.  So this is not going to be the same HTML that you're seeing right here.  It's going to be the result of rendering this and evaluating anything that needs to be evaluated.  And then, then and only then, will I take that result and stick it into that Div tag.  And by doing that, I've been able to separate out the main layout of that single-page application  from all of its different mode layouts.  And the end result is kind of the same.  Is this thing still running? Yeah.  Now, it's not going to look any different.  It works exactly the same.  But it's done a little differently because right now, when I first ran this,  the only thing that loaded was the main layout page and that one view that I'm displaying, the list.  And I never, ever press edit.  The other user control, the other CHHTML file is never brought in.  So that HTML was never rendered.  And if that's a really, really large amount of HTML, it could save you on some resources.  So both techniques are important.  Don't jump right to this technique because you want everything to be at the nanosecond level  because you may not need it.  And if you don't need it, it's a lot easier to program the last one.  But I felt it was important enough to give you both techniques.  Yes. You call me sir, sir's my father, man.  I'm an American. You call me dude.  What can I do for you?  This scenario is also a useful offline scenario.  When the user can use your application in offline mode, then you will use the first one, right?  That's exactly right. If you're offline, you can't go to the server.  Then you would have to use the first one.  Yeah, absolutely. Yeah. Way to think ahead. Absolutely.  Yeah, wouldn't it suck if you use the second one for everything and then you have to get on an airplane?  Exactly. It doesn't work.  Yeah, because you're using WebAPI to go get something, which means you have to be accessible in the server.  So, yeah, definitely a good point.  All right. Now, everybody having fun?  All of this is kind of cool.  Now, imagine yourself writing this great application that does SPA  and I run it and I switch this to another view and then I switch this back and then I switch this.  And I'm like, ah, you know what? I changed my mind.  Let me go back to the list. Let me hit the back button and poof, I'm back here again.  And that sucks. And you're going to get that. It's important.  I don't want to leave you without this.  And I'm not going to spend a whole lot of time doing browser history because I do an entire talk on push state, on browser state.  But it is important and I gave you some good samples for you to look at the code.  You're going to get a lot out of my code. I take a lot of pride in my demos.  When you deliver a view through NBC from the server to the client, at that point in time,  NBC or the Web will actually push the state of the browser onto the browser history.  If you're doing everything in the browser only and you don't go back out to the server like I'm doing here,  right here, I didn't go to the server. I didn't go to the server.  This is all done with the magic of JavaScript. I've stayed in the browser.  The only piece of history the browser has right now is the initial page that it got to.  Which means what's the page before that? The menu page, right?  So the minute I hit the back button, what happens? You go right out there.  And this doesn't give you a polished application.  What it does give you is a really pissed off user.  Because the user is going to change a lot of stuff and they're going to press this and the screen is going to change.  They're going to change more stuff and they're going to say, oh, shit, I messed up.  And they're going to hit the back button and they're going to go all the way back.  And that's going to make a really, really angry user.  Sometimes I like to make users angry. It keeps them on their toes.  But most, a lot of times, the user is paying the check too. So you don't want that.  So in HTML5, you have the ability to actually push state to the browser itself.  Which means you're effectively fooling the browser into thinking that something has changed in the URL.  And it needs to push something onto its history.  Browser history is just a stack.  And like any stack, you're going to push something into it. You're going to pop something from it.  The problem is that by default, the only thing that pushes onto the browser history stack is when a new page renders from the server to the browser.  And when you back button, then it pops from the stack.  What we can do today with HTML5 is that we can manually push, using JavaScript, to the browser history stack,  to make the browser think that there's more things in its stack.  And then pressing the back button will pop something from the stack.  And we need to be able to tap into an event that tells us what's just been popped and what does the stack look like now.  And now the hard part is that it's up to me to manually change my view based on the current item on the browser stack.  It sounds complicated and I wish I had more time to get into a lot of detail, but I'm going to show it to you anyway.  So here's the history tracking view.  It looks exactly the same as the previous example, so we're not going to spend a lot of time in this view.  The view model is where it's a little different.  What I've done with the view model, all this is the same.  Load people, save person, all of this is the same.  What I've done is that I am subscribing.  This is a knockout feature.  You can subscribe to a property.  Remember that view mode property?  In knockout, you can actually write a subscription so that anytime anything changes the view mode property, this gets fired.  Think of this as an event.  So now anytime that anything in my knockout view model changes the view mode property, I know that the view is going to change.  So this is where I want to affect the browser history.  So I wrote some code here that cases on what my mode is.  Is it list mode or is it edit mode?  And then what I'm doing without getting into too much detail, because I still have one more thing I need to show you before you leave,  I'm using a helper class that's down here at the bottom that I wrote.  I'm going to let you play with the code.  And what I'm doing is that I'm actually pushing onto the browser stack the code name list mode.  This can be anything, but it's from my own sanity.  I made it the same as this.  I'm pushing the code name list mode or edit mode with whatever the URL I want it to look like on the browser.  Now notice in this example, the next example is going to be different.  In this example, the URL is the same.  Home history tracking.  What's important here is this here.  Because now what happens is that I'm also subscribing to the Windows on pop state function.  This is what's going to get fired when you user presses the back button.  And what's going to come into here, our state is the code.  And notice what I'm doing.  I'm doing change of the view.  So anytime that I change the view, I'm pushing whatever that view is, list mode or edit mode onto the browser stack.  And anytime the user presses the back button, whatever that last push was gets changed here.  And it's this change view that causes my actual view to change.  The browser doesn't keep track of that memory.  It doesn't know it because it was all done with JavaScript.  The browser just keeps track of this or this.  List mode, edit mode, list mode, edit mode, list mode, edit mode.  And then you hit the back button, it goes back to edit mode.  Hit it again, back to list mode.  Hit it again, back to edit mode.  And it's me that's actually causing the view to change.  This works seamlessly when the next problem is an actual push from a blog page.  Well, that's going to be a totally different view.  And the process is going to start all over again.  It won't be your function.  No, but my stuff still stays in the browser stack.  So if you go now to a different view and you start changing that, and then you back your way back to this one,  all this is still in the browser stack.  So it'll still work just fine.  So the appearance of it is actually very cool because watch what happens now.  I'm going to press edit on Brian.  This is all with JavaScript.  Hit save, edit on Carl.  Hit save.  Now, the back button goes back to Carl.  Look at the URL.  Stays history tracking.  Now go back to here.  Now you should go back to Brian, right?  I would need to do more work to keep track of the actual person.  I didn't do that work.  But you saw that the view actually gets tracked.  Now the URL didn't change.  Why did the URL not change?  Because there's only one URL.  And that's this one right here.  That's what the next example is.  I wish they would have made these things an hour and 15 minutes.  Because I got three minutes to show you this last piece here.  When is the next talk?  Is it a 10.15?  A 10.20?  If I take like five minutes, anybody going to get pissed off?  All right. Nobody's going to give me a red card  because I took an extra five minutes.  Because this stuff's important.  Now watch this one.  I have this home controller here that's been driving everything.  This home controller is going to drive another view  called multi-sub-entry.  The idea here is that now I'm going to give you a different URL.  Because this is very, very common. Who uses GitHub here?  So have you seen how cool GitHub is?  GitHub does everything with SPA.  So every time that you click on folders in GitHub,  all it does is change that one section in there.  But have you paid attention?  Every time that the folder changes in GitHub, did you notice the URL changes?  Which means you can actually target a specific folder structure in GitHub  by going right to the URL.  So what I have here is that I have, this is a little more complicated.  I have a view called multi-subview entry.  That's going to give me three different states.  Step one, step two, step three.  Now I've shown you SPA so far with a view that has two states, two modes.  List view and edit mode.  However, I haven't given you a way to use the URL to jump straight to one of those modes.  I forced you to start at the beginning and then manipulate the mode  using what I give you in the view.  Here I'm going to do another thing.  I'm going to let you go to here and I'm going to let you jump into step one,  step two, or step three from the URL.  And I do that with the help of an MBC model.  So notice I'm returning a view.  This is regular view rendering, but I'm rendering it using a model.  The model has this initial state.  You could also do initial ID if you needed to identify like an employee record or something like that.  But let's just deal with state.  So I have this one property called initial state here.  Now look what initial state is doing.  Mode one, mode two, mode three.  Same view.  Now take a look at this view.  This gets really cool.  So here this view is why I love using knockout with MBC because I mix these worlds together.  So now I've delivered an MBC view with a model object that's got an initial state property.  There's my model object, which means my initial state for those of you guys who's an MBC developer here?  Okay, most people.  So there's my model initial state.  Now look what I'm doing.  This is a server side property that I'm converting it to a JavaScript variable by filling it by saying var initial state equals.  And then in quotes, I say razor syntax modeled out initial state.  So now that's step one, step two, step three is inside a JavaScript object.  Now I can send that into the view model right there because now it's up to the view model.  Now look, the rest of this view is not complicated.  It's exactly what you've seen in the past.  There's my three divs.  They're only going to be visible based on the content of view mode.  Mode one, mode two, mode three.  I'm going to show this or the other or the other.  So now it's all about the view model, which now received this initial state.  And if I go to the view model, which is right here, there's the initial state.  And then if nothing came in, I'm going to set it to mode one.  But if something came in, then I'm going to go to step one mode, step two mode, step three mode.  And these functions are simply going to change the heading, a property called heading, and it's going to change the view mode.  So heading and view mode are the three things that are changing, right?  Let's go back out to the view and let's take a look at right here.  There's heading and then view mode simply will toggle between step one template, two template, and three template.  Now to polish this up, to make it a really, really clean application, look what I'm doing.  I'm doing my old browser state thing.  So now I'm subscribing to the view mode and based on the mode, I'm pushing to the browser.  But look at the difference now.  Excuse me.  The difference is that now you're seeing three different URLs.  And that was my choice because not only am I giving you, is it two different things?  They look like they're same, but two different things.  Here is where I'm giving you the ability to URL yourself right to a specific step.  Here is where I'm pushing into the browser state with a different URL so it will change.  I could have made this the same for all three and I would still allow you to target a specific step with the URL,  but then the minute you start doing on the back button, this is what you're going to see in the browser.  You want the two to match and you got to do this manually, unfortunately.  Watch what the effect of this is.  It's actually quite cool.  Here's sub view one.  Actually, let's start at two.  Now, notice it says this is the second view and it gives me buttons for step one and step three and look at the URL.  Step two, 102.  That's 102 is that identifier, which is meaningless for our demo.  Now, watch what I can do.  I can jump right to step one by going to the URL.  Watch this.  Now I just jumped to step one.  So now I have a way to actually get into, remember, all three steps, step one, two and three are all driven by the exact same view.  They're just three different SPA modes of that single view, but now I can use the URL to jump right to each any one of them.  And now I can go to step two.  See the URL change.  Step one, the URL change.  Step three, the URL change.  Now let's go to the back button and see what happens.  Now I'm back to one.  Now I'm back to two.  Notice my URL is in sync on the browser bar.  Now I'm back to three.  Back to one.  Back to two.  And back to the menu.  So I get a nice polished application.  The user is getting pissed off and I still get a nice big check in the mail.  Right?  So guys, I hope this has been helpful.  I think the best part of this is probably going to be if you download the code, I've tried to give you, I pride myself on my ability to write demos.  So if I don't have time to show you something in the level of detail that you want to see it, I'm hoping that downloading the code gives you a really, really good kickoff point to write these things.  This is very, very cool.  In my opinion, the last line here is the key one.  You'll never develop a conventional ASP.net MBC application again.  Once I start using this stuff, knockouts become almost part of my regular stack.  No matter what kind of site I'm writing, it's always going to be done this way.  And since I'm coming from a WPF world, this just made sense.  When I started doing knockout MVVM, it just felt right.  This is the way I need to write applications.  Concentrate on the view model, let the view refresh itself based on my state changing, which is the same way that I think when I do WPF.  So now I don't have to think in two different ways and I have more time for scotch and cigars.  So I hope you guys enjoyed yourselves.  I got a session at the end of the day today on dependency injection on number seven, I think.  So come back and see me and thanks for coming.  Hope you had fun.  Thank you.  Thank you.  Everybody needs to follow me on Twitter, okay?  I don't have enough followers yet and that bitch from Jersey Shore, Snooki, she had like 90,000 followers.  That pisses me off.  Thanks, man, appreciate it.
Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_0_13139.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_13140_13847.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_13848_13943.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_13944_15011.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_15012_17015.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_17016_17807.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_17808_20303.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_20304_26123.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_26124_26603.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_26604_26723.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_26724_26807.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_26808_27299.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_27300_27455.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_27456_27851.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_27852_27911.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_27912_28055.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_28056_28295.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_28296_28691.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_28692_29051.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_29052_29207.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_29208_29651.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_29652_30275.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_30276_33047.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_33048_36203.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_36204_36539.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_36540_37391.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_37392_38615.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_38616_38687.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_38688_39635.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_39636_39983.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_39984_40055.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_40056_40187.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_40188_43247.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_43248_49895.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_49896_51287.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_51288_52847.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_52848_53111.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_53112_53279.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_53280_53411.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_53412_54059.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_54060_54707.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_54708_56003.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_56004_56051.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_56052_56147.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_56148_56399.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_56400_56567.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_56568_59951.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_59952_60563.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_60564_61235.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_61236_61379.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_61380_61499.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_61500_62855.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_62856_62939.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_62940_63491.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_63492_63623.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_63624_63971.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_63972_65867.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_65868_67163.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_67164_68531.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_68532_68795.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_68796_69083.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_69084_71711.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_71712_71987.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_71988_72503.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_72504_74507.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_74508_74555.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_74556_74759.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_74760_75455.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_75456_75719.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_75720_75827.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_75828_75935.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_75936_76919.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_76920_77387.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_77388_77483.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_77484_77867.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_77868_78299.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_78300_78815.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_78816_79163.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_79164_81443.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_81444_81635.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_81636_81779.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_81780_82919.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_82920_86207.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_86208_86495.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_86496_86663.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_86664_87143.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_87144_87503.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_87504_89807.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_89808_92723.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_92724_93131.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_93132_93215.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_93216_94643.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_94644_94955.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_94956_95051.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_95052_96131.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_96132_96503.png Miguel_Castro_-_Doing_SPA_with_MVC___KnockoutJS-68375235_96504_98684.png