What do you want to learn?
Leverged
jhuang@tampa.cgsinc.com
Skip to main content
Pluralsight uses cookies.Learn more about your privacy
Building HTML5 and JavaScript Apps with MVVM and Knockout
by John Papa
Learn how to build robust and maintainable Web applications with JavaScript patterns, MVVM, and KnockoutJS.
Start CourseBookmarkAdd to Channel
Table of contents
Description
Transcript
Exercise files
Discussion
Learning Check
Recommended
Getting Started with Knockout and MVVM in JavaScript
Introduction
John Papa: Welcome to building HTML5 in JavaScript apps with MVVM and Knockout. My name is John Papa, and in this Pluralsight course, I'm going to walk you through what you need to know to build web apps using Knockout Library and the MVVM pattern along with JavaScript HTML and CSS. Along the way, I'm going to explore things like how to get started with Knockout, show some valuable resources and tools, demonstrate the various bindings that Knockout offers, and go through the templates, the control flow, binding handlers, and many, many other things that it has and offer some tips and tricks. In this first module, we'll start out by taking a look at the state of JavaScript development today, and how data binding in Knockout can play a role in that, and then we'll take a look at the MVVM pattern with the Knockout specifically and show you how you can use good separation patterns not just with other technologies but also with HTML5 and JavaScript development. Then we'll jump into some tools such as jsFiddle and show you how you can use some co-chairing tools like this to mock up some quick examples and to run some quick tests. It's great for sharing, especially if you don't have another environment like Visual Studio. And then we'll demonstrate how to use Knockout with Visual Studio, how to set up a project, look at the different extensions that you can use that I find really helpful not just with Knockout but with any JavaScript or HTML development that you can do. And then we'll wrap up this module by talking through some different resources that you can use when doing Knockout and pattern development. These resources include things such as where to find the source for Knockout so you can link to it, documentations, forms, other examples, some tutorials, some quick tips, and a great place that you can ask questions along the way as well. So with that, let's dive right in to using Knockout.
JavaScript, Data Binding and Knockout
Before using Knockout, it's important to understand the different scenarios where Knockout can be very useful. So to start off, we'll take a look at separation of concerns as it appears to JavaScript in HTML5 development. Now it's not just for JavaScript development and separation concerns. It can be used in many different technologies and strategies, but with JavaScript itself, we're talking here about separation of the structure, which is the HTML from the presentation, the CSS, from the behavior, the JavaScript. Can we do that with JavaScript? Certainly, we can, and why is it important? Because we like to make things more maintainable, making it easier to use, and it kind of follows along with the (inaudible) principles or at least the S in solid, which is single responsibility. And then how do we deal with the Y pattern that JavaScript development? Do we use something like MVVM or data-binding structures? How do we structure our JavaScript? Do we do something like what Douglas Proffer prefers to use with the module pattern from his book, "The Good Parts", or the revealing module pattern, and how do we separate these things out? And, finally, what about data and bindings? All apps love to use data. So when you have to load you data up from someplace such as an Ajax service, and you're dealing with (inaudible) on data, how do you load that data onto your screen? How do you respect changes from the user? How do you push and pull them between your source object, maybe JavaScript, and your target elements up in HTML? Can you use something like bindings? Well, Knockout can help solve a lot of these different scenarios and put some structure in place. So they're not just pieces of the puzzle anymore, they actually fit together nicely for you. So what is Knockout? Knockout allows you to have rich clients (inaudible) activity for your UX provide a good pattern, and it gives you a good separation of behavior and structure. It uses things like declarative bindings to be able to help you bind your UI elements, this case HTML, or maybe even CSS styles and classes down to your source object. So you get that MVVM-like pattern, and we'll talk a little bit more about what MVVM is in a very short moment. But does your browser support this? Well, here's a quick look at the different browsers that Knockout supports. You've got IE6 and up, Firefox2 and up, and then, of course, the latest versions of Chrome, Safari, and Opera. Now, I certainly hope you're using something more recent than IE6, but if you are, rest assure it still works. So what are the key concepts of Knockout? We've got the dependency tracking with observables, which if you're familiar with things like (inaudible) technologies with Silverlight or Windows 7 or Windows 8 metro style, you can relate this to the I notify property change interface, which basically means that you're going to have a property, some source object, and that's property, let's say first name. When it gets loaded or changed, it's automatically going to notify the UI that's bound to it, maybe one or more places that, hey, I've got a new value, and that UI will reflect that change. And then also you have the option of when that UI might change the value to automatically update the source object again. The second concept is talking about declarative bindings. This is where you might deal with binding your source objects to your elements, your target elements through the HTML itself. So instead of taking JavaScript and saying go find this element by ID or by some other means and bind it to this value and this JavaScript object with my (inaudible) data, instead of doing that through code and then pushing it into the UI and then pulling it out of the UI, we can do that through declarative bindings where inside the HTML element itself, we can say this element is going to get this attribute's property or this value from this source object down in my JavaScript object, and that can work both ways as far as pushing data into the UI and then pulling it back out. The third key concept is dealing with templating where you might have repetitive structures in your web page, for example, like rows in a list box or you've just repeated LI's in a numbered list or maybe even rows in a table. So anything you might have that repeats or even just a small view on your screen you can use templates to do this. This is kind of synonymous doing item templates or data templates with (inaudible) technology as well, or if you're more familiar with JavaScript development, you can use things like (inaudible) templates as your template engine of choice with Knockout, or you can use the native templates with Knockout, or if some other third-party templating engine. It's really up to you. So let's show you quickly how you can do this in three steps and set up a page. Here's an (inaudible) text box that's going to have a declarative data binding, which is the first step you want to do to find the value for that input text box to the first name property of some objects, some source object. And then we've got some source object, in this case called My View Model, which has a property called first name, and it's using the Knockout observable property, here in this case using the value of John as a default, and it's going to bind that value up to the first name property inside the input text box. So what's happening here is the data bind attribute in the first element is saying set the value to first name, and then, of course, there has to be a first name matching property of type observable to actually receive those changes. So now somebody types in John or Fred or Sam in the first box, it's going to send those changes back down to the view model as well when, if something changes in the My View Model dot first name property, it'll also send that value back up to the UI. And the way you glue all this together is using the KO dot apply bindings method. This method here basically says go take the view model that I just created, and make it the data context for, in this case, the entire screen and all the HTML elements that are on that screen. So we talked a little bit here about the three different steps to get going with Knockout. Let's dive into an example using the jsFiddle here on the screen.
JavaScript for Developers: Demo
So here's our first example of Knockout where we can see, we've got our HTML up top, our structure separated from our behavior on JavaScript at the bottom, and the results of it over here on the right-hand side. Now we can see that the info tag has got a data bind attribute where this is the HTML5 compliant attribute that Knockout looks for and says, alright, we've got this value built in binding. So we're going to put the value of the first name property inside of this input text box, and that's why we see John showing up over here. So it's got to look for some object that it's bound to as its state of context, and that object that it's bound to is My View Model. So My View Model is defined, and then it's got a property called first name, which matches up here, and the first name is defined as a type KO dot observable, which is a function built into Knockout saying make this property observable. So any changes that happen in the view model get notified of the UI and vice versa, and we're going to default the value to John just as something shows up immediately. And then how you glue these together and set the data context for the HTML is by saying KO dot apply bindings. Here we can say, alright, take the view model we just created, and apply it to the entire page. That's in context. You can also use some other overrides to set specific elements as the context, but in this case, we're setting the whole view model. So when we run this, we can see the value John shows up, but we can also change that value John, too, to something like Sam. But how do we actually test this? So we can type in here some other elements. We can do some more binding. Let's say we wanted to type in some kind of a span, and let's just set it up real quick where we've got a span, and we want to actually display the value of first name just to make sure that that value is coming out. So here we've got data bind, and we're going to set equal to, if I can type. The text binding, first name, and then we're going to set that inside the span. So what should happen now is we've got an input box where we can type in the name, and we've got a span, which is going to show the value of first name. One quick difference here is that an input box, I'm going to use the built-in binding called value, which is going to display the value for its input, and in span, there are no editable fields. It's all just text. So here we're just saying just spit out the text, and find the binding as appropriate for that particular element. We'll explain more about what these built-in bindings mean in the second module. But here we run this. We can see John shows up because that was a default value, and it shows up below that as well. And then when I change John to Landon and leave the field, you'll notice that the binding also updates down in the span.
MVVM with Knockout
To better understand Knockout and how it works MVVM, it's key to understand what MVVM is in the terms of Knockout. MVVM is simplicity is just a separation pattern and a way to organize your code structure to make it easier to maintain and to deal with separation of duties and responsibilities. So MVVM itself is a separation pattern. Again, separating out your responsibilities for your model, your data, your view, which in this case is your HTML, your screen, and your view model, which we're writing in JavaScript as you saw in the previous examples. It's not technology specific so you may have heard MVVM being talked about with (inaudible) technologies, but it can work with anything that deals with data binding, in this case, dealing with Knockout, with JavaScript, and with HTML. And that's it. That is the concept of MVVM. It's a separation of concerns. Now there's other things that can go with MVVM, but, really, it's all just helpers that can help you along the way. So dissecting a little bit about what MVVM means to JavaScript and HTML specifically, first let's look at this diagram. We have a view, which in this case is HTML. We have our model, which might be (inaudible), and in between those two, we have some logic to separate how we present that model (inaudible) data into the view itself, and that is our view model. So we have our view, our view model, and our model. The model itself is the data. It's, in this case, the JavaScript object that might contain our properties, like first name. The view is the web page, the HTML is the user-friendly presentation of what we're showing on the screen through different tags like inputs and spans and (inaudible) and any other semantic tags you might be using with HTML5. So basically so far we've got our data, and we've got a place to put it, and then we have the view model which ties these two together. It contains all the behavior for the view that the view needs and can aggregate one or more models to show the data inside the view. So in this way, a view might need to take advantage of the model, maybe a person object in some case, and show that person on the view, but there might be multiple views that need to do that. So instead of having the model being imbed in every view, what we can do is create a views model or a view model, in other words, which is really just a object, a JavaScript object which aggregates one or more models, and it pulls them together and exposes the properties and methods that that view needs. So how does this look? A view model might be, in this case, using an object literal. We show a bunch of properties, and we're showing those properties being defined as using the Knockout observables. In this case, all of those properties are going to be using two-way binding between the view and the view model. The view model's the source. The view is the target. We can also see there's a guitar model property. This one is actually showing you how you can do an object graph diving into other properties of other objects. So it's not just a flat (inaudible). You can actually have, like, customers and customers' orders and order details and so on. And, finally, we can see at the bottom the show details method. Show you that you can create a function inside of the view model to add behavior for that view. So now we've seen how this works and what MVVM means in Knockout. Let's dive into quick examples on how you can actually write code two different ways by creating a view model using JavaScripts. ( Pause )
MVVM with Knockout: Demo
John Papa: This example demonstrates how it can separate at the model from the view, from the view model, and we'll start with the view itself. Up top, you've already got the HTML, which is our view, and we can see we're binding, too, using Knockout binding the text to (inaudible) description for this span. So the short description is going to be a property on a view model, which you can see down here, in the view model and the JavaScript. Same with description, which we can map down to the JavaScript as well, and then format currency is a function on the view model, and then sale price is a property on the view model. So here we would see format currency, which is just a member, a method member of the view model, and using the sale price, which is a property on the view model. So we can see the interdependency between the view where it's declaratively saying here's my bindings. Go find that view model, and these are the properties that you have access to. And we can do that because here is where we're setting up the applied bindings to say take this view model and make it the data context for all of my HTML, my view in this case. So to this point, we're seeing how we can set up a view model and a view, but where does the view model get its data from. That's where the model comes in to play. In this case, you've got a model called data which we're storing our (inaudible) data in, and we can load that up and actually just store it here inside of our view model. Of course, we can take that model and go much more complex. In most examples, we would, and we'll see those later on where we actually have different models in our view model loaded from different places as well, not just hard good. So this example demonstrates how to use an object, literal inside the view model, which is one way to do that in JavaScript which is very popular. Another way is to set up the view model using a function. So instead of an object literal, we just create a function, this case set it to a view model, and then we set all of our properties up using this dot property. In this case, we've got sale price setting up to be an observable, and we set the pricing from the model itself. We have the same properties and features as we had in the previous example. It's just one big difference here is that instead of using object literal, we're using a JavaScript function. And if we go back to the object literal, you can see it's a little shorter syntax. It's really easy to get out of the gate with an object literal. You have a little more ability to do different things with a function, and there's other patterns you can take advantage of, too, and we'll take a look at those in later modules and the pros and cons of different JavaScript patterns that you can use with Knockout, but for now, it's just important to see the separation between the view itself, the view model, and then the model, and that's how simple MVVM is with Knockout. ( Pause )
jsFiddle
John Papa: In the previous examples, I was using jsFiddle to demonstrate how JavaScript and HTML could work together. So let's take a step back and take a look at the tool itself, jsFiddle, which is a free tool at jsFiddle dot net. This is basically what I call a chalkboard for ideas. You can quickly take an idea you have in HTML and JavaScript, and you can share it out with a colleague or a friend or with the Internet through some other tool like stack overflow, and you basically just go in there to jsFiddle dot net. I usually create an account first, and once I have my account open up, I edit my HTML, my JavaScript, and my CSS, and then I can debug it, I can execute it, I can share it. And it's great because you can take someone else's code or your code, and you can fork it off, make a new fiddle, which we call here to basically just your HTML JavaScript hand, CSS put together, and create a new version of it so you can have different ideas that you have out there. One of the nice things, too, is it allows you to create references to libraries like jQuery, jQuery UI, Knockout, or any other library that you have access to. So how does jsFiddle look? Here, we see the screen that we saw earlier, and we've got four panes of windows basically. In the upper left, we've got out HTML window, and that's where we stick our HTML for all of our content. In this case, we're going to put that up there with our data bind attributes with our Knockout declarative binding. Then in the upper right, you've got your CSS for your styling that you can include optionally. And then the bottom left, you've got our JavaScript window where we put our view model and the bindings that, the applied bindings method that links the view model up to our HTML for structure, and then when you press the run button, it actually runs, and the results show in the bottom right-hand corner of the screen. So you can see here we've got the four elements that you need to actually just test something out quickly, and you don't need a whole environment like Visual Studio that you need to run to get things up and going. So here we can test out things really quickly. You can use the debugging tools that are built into your browser of choice, and over on the far left you can also see that we can reference different resources. Here you just type in the resource, the URL to it, hit the plus button, and it'll refer to it. In here, you can see I've typed in the full URL for Knockout that I can use in my particular demo for this jsFiddle. But now that we see how it works in the slide, let's go take a look at a demo and actually demonstrate how it works and some of the other features that you can use. ( Pause )
jsFiddle: Demo
John Papa: Sometimes I just want to fiddle around and create a JavaScript, an HTML solution where I'm testing out an idea, and that's when jsFiddle is really great. Here's an example of using Knockout inside of jsFiddle where we've got a fiddle that I've created through my account at jsFiddle dot net, and one of the features you can see automatically is I've logged in here, and when I click on my name, I can see dashboard, and here are all the different fiddles that I have, and you can name the fiddles. You can go click on a fiddle that you want to receive, or you can create a new fiddle. So in my case, I want to stay on this particular fiddle here that I've got, and I can actually add names to it. Like I call this a Knockout overview and give it a description. You can also add other information to it as well. One of the things you'll almost always do is want to go and manage your resources. In this case, I can type in Knockout js, or if I wanted to, I could show you here. We can type in the actual Knockout URL, which if you go to the Knockout home, you can get the source tag, and go over to get (inaudible), and you can actually navigate to Knockout, and you can type it in here, and then just hit the plus sign, and you can see Knockout2 is now referenced. Now when I run my page, in this particular case, we've got a view model down here that's being bound up to the view, my HTML, and when I click on this button, it's going to load in all of my products that I have and their prices. So here jsFiddle is showing me I've got my HTML, my JavaScript, my CSS, and then my results. I can manage my references, or I can add things in like anything else. I can Knockout plug in if I wanted to or some other library. Inside my framework, I can add in (inaudible) if I want to do that. I can actually specify the main library I'm going to use here for mu tools or for jQuery. You can also tell if you want to do it on document ready automatically. So if you don't want to deal with having to set up an on document ready yourself, you can actually just assume that's what it's going to be using if you select this option. There's a lot of cool examples you can do here with jsFiddle. And then across the top, we've got the run button, which runs the code for you. Then you can update the button anytime you want to say something or you can do a control S which will create new versions. So if I come into here, let's say I typed in some kind of new line. Let's say I typed in a exclamation point, and I hit control S, when I save that in here, it's going to give it a different version number. So it's going to version these particular fiddles for you. And let's say it was a minor change. I could set that back to being the base if I wanted to, or I could revert back to an older version. So it actually tracks the different versions every time you click the update. You can also click fork, which let's you fork into a new fiddle. So if you see something here that you really like, and you want to take it in a different direction, but you don't want to lose what you've already started with, forking is a nice way to do that, and you can also fork off of somebody else's fiddle if you see someone's that you want to use. Tidy Up is a nice feature because it will actually reindent messy code. Sometimes when I copy and paste code into fiddle, I'll click this, and it'll actually change things around. Give you an example of this here, I can type in some JavaScript, and let's say I had some bad indentation like that, and let's add some others here. Some spacing, make some tabs. When I hit Tidy Up, it'll actually go ahead and reindent it for me. You can also use jsLint on it to run on the code to basically check to see if your JavaScript is OK. You can share it out using something like Facebook or Twitter, but the most important thing I do with jsFiddle is to mark up some quick HTML and JavaScript, see how things are going to work together, reference my libraries, and then I can actually run through it, and make sure it all works OK. And if there's a bug in here, like, let's say I typed observable wrong right here on this line, and I just accidentally type that. I could use the debugging tools in here, and built into Chrome or whatever browser I'm using, and now when I run this code, and I click the button to load, you'll see down here I've got a uncaught error on observable, because that's not a good word. I click on there, and I can see, ah, alright. I misspelled that word. So you can actually set break points in here as well if you wanted to, and then you can run and stop right on the break points, and then I can come back over here, and I can fix the code when I need to, and everything is good to go. So you can see jsFiddle has got a lot of value to it where you can get up and quickly running with using your code where you don't have to have a full-blown (inaudible) to do so. ( Pause )
Using Knockout in Visual Studio
John Papa: One of the nice things about doing development with JavaScript inside of Visual Studio 2010 is where you have features that maybe aren't built into the tool itself. There's Visual Studio extensions that can enhance the experience. So one of the things I like to do is I use some of the free extensions that I'm listing here that we'll demonstrate in a moment like New Get which will manage my third-party libraries for me. So I can automatically link into things like Knockout or jQuery and get notified when there's a new version, or I can use Web Essentials, which basically does code collapsing in vendor specific CSS properties, and it does a lot more as well, and that's written by (inaudible) Christianson, and it's one of my favorite Visual Studio extensions that I use. He's also written another one called CSS Cop, which is a little bit newer, and it catches some of the common CSS issues. It's kind of like a code analysis for CSS. And then we've got jsLint, which is a code analysis tool, which allows you to check your JavaScript. Another one here that's really nice is small extension is the WOVS default browser switcher. That one allows me to quickly change the default browser inside of Visual Studio so I can test my code out in different browsers, which is great. And, of course, Web Center's update, which allows me to use HTML (inaudible) validation. Now there's one not so free item, it's not free at all. Read Sharper, which has a free trial, but it's one of my favorite extensions. It allows me to JavaScript refractoring. For that alone for the JavaScript and the CSS refractoring, I really like to use this tool. And we'll take a look at all these tools throughout the course, but let's take a quick look at each one of them and how we actually add them into Visual Studio (inaudible). ( Pause )
Using Knockout in Visual Studio: Demo
John Papa: Visual Studio 2010 allows you to install extensions to enhance the experience when you're developing with JavaScript or other tools, and to do that, you can come up under here under tools, extension manager, as long as you've got ultimate or professional or one of the non-express versions of Visual Studio. You can install any of the extensions we've talked about earlier. Here, we can see New Get. It showed up on our installed extensions. And so (inaudible) the other ones we looked at. There's also an online gallery. So one of the ones I mentioned was Web Essentials. So I can go into here, and I can search for anything called Web Essentials, and then it's going to look online to see, there we go. Web Essentials what we want. It's by (inaudible) Christiansen, and this does things like adding in vendor specific extensions for CSS. It does JavaScript brace matching, which I really, what I want to use it for. So I just click install, and then it brings me out to the web page and shows me all the different features, which is kind of nice. It gives a little color highlighting. It shows you previews of fonts that you have, and you can also see down here, we've got some features for JavaScript for custom regions, code collapsing, same word highlighting, minifying JavaScript. Really nice features that you have built into the Visual Studio tool then. So I can use that here basically by looking at our online gallery, and you can search by type, too. So I can type in here JavaScript just to see what other kinds of libraries there might be available. And, again, I can look at my installed extensions, and when there's an update, all I have to do is click on updates here, and I can see any extensions that have updates since the last time I installed them. And Visual Studio, when it loads up, it'll actually check for you as well. So this is just a quick preview of how to use some of the extensions and to load them up. We're actually going to take a look in the next couple of demos on how to use some of these along the way.
Begin Coding with Knockout
When you begin development with Knockout and Visual Studio, one of the first things I recommend is to go up to the Knockout website and download the JavaScript files for Knockout itself, and you can do that a couple of different ways. One is to go to the Knockout website, click on the source link, brings you (inaudible), and then you can download the latest JavaScript files. Now you're going to get two files. One will be the debug version, which you can see here is basically labeled diversion dot debug, and that contains human readable code for JavaScript, which is great for debugging, and then you also get the minified version of Knockout, which is what I recommend using for production. The second option you have is to use the Visual Studio extension called New Get, which we demonstrated earlier, and we're going to take a demo quick here and show you how New Get works so you can actually load in the libraries that way, and there's some advantages to doing it both ways, and we'll talk about both of them. The next thing we're going to look at is how you deal with IntelliSense with Knockout. Now with Visual Studio, you can get IntelliSense with Java files by simply including the reference path as we're seeing here on the screen. So by doing that, then anything on the page that uses Knockout when you do ko dot observable, for example, you're going to see observable show up on the IntelliSense just like you would with C Sharp or any other language that's built into Visual Studio. And this basically just becomes a comment in the file. This has to be the first line of code in that particular file for it to work, though. Or, if you prefer, you can use one of the extensions I mentioned like Resharper, and it will automatically include IntelliSense for your JavaScript files. Let's do a quick demo now where we actually reference Knockout using the downloaded files and also doing it through New Get. ( Pause )
Begin Coding with Knockout: Demo
John Papa: Now let's create our first Visual Studio project with Knockout, and to do that, first we'll click on new project, choose web, empty web application, because we really don't want anything in it yet, and we'll call it getting started (background noise) with Knockout. And we'll hit OK, and it's going to generate basically an empty web project for us. Now the next thing we're going to want to do is actually reference the JavaScript libraries that we may want to use in our project. Now we might want to use jQuery, which is pretty popular, but, of course, we're going to want to use Knockout. So there's two ways I recommend on doing this. One is to actually go up to the Knockout website and then click on the source tab, which will bring you over to the downloads page. So I (inaudible), and then you can click on the downloads page for Knockout, and you can see here he's got laid out the minified version of Knockout and the debugged version which are the latest ones, 2 dot o dot o. And then if you do, you can download this whole thing as a zip file. First, if we come up into the address, we can see what the minified looks like, and then here is the full-blown debugged file. But we can actually download the entire zip file containing all the Knockout files that we need, and then put them on our hard drives and then actually include them in our projects themselves. But then whenever there's a new version, we have to come out here, and we can watch it through (inaudible). We have to actually come out here and actually download the new ones. Another way of doing this is to use New Get. So because I installed New Get as one of the extensions, I can right click on my solution here, click manage New Get packages, and I can see there's nothing installed already, but I can go online, and I can search for popular Net Get packages, or I can type in something here like Knockout, and it's going to search the Internet to see are there any New Get packages with the name Knockout in them. And here we can see Knockout js, and then a couple of extensions like Knockout mapping. So here, this is the one by Steve Sanderson, and the most recent version, and we're going to install it. Now what Visual Studio will do is it'll download those files, the same ones we looked at, and it'll actually put them inside of a Scripts folder. Here, we can see the debug file, which is going to look just like the file we saw up on (inaudible), and then here is the minifier file that we have. So I'm going to close these ones out because we don't actually want to modify them by accident, and then we can see here they're already up there. Now one of the nice things about this is that if a new version comes out, Knockout, New Get, and Visual Studio will automatically notify you so you can update these and then manage that reference through New Get. You simply come into New Get again, and we can do that through References, say manage New Get packages, and we can say installed, and if there was a new version here, we could say, alright, go ahead and update them. We can click on the update tab to see if there are any. Now once we have Knockout, we actually want to create some web pages. So let's go ahead and add in a new file. So here's our new file. We're going to create an HTML page, and let's just call that home. And inside of our page here, we can see we've got our HTML, and let's just create a quick little tag in here. We'll create a span, and inside of that span, we're going to put a data bind attribute to use Knockout. We're going to tell it to bind the text value equal to a first name property. And, remember, Knockout isn't even being used yet. So we have to actually write some JavaScript code as well, and we can do that in a separate JavaScript file if we want to. So one way to do that is to come into here and say add a new item, and we can go down and create a new JavaScript file, and just for grins I'm going to call that home dot js, and I'm actually going to store that in my Scripts folder. And then my home file here, my HTML file, I'm actually going to reference the home js by dragging it from Visual Studio over into my window. So now I'm actually referencing that (inaudible) file, which doesn't happen to have anything in it yet, and the first thing I'm going to do is add IntelliSense for actually using the Knockout library here, and Visual Studio will recognize this, and then it'll look into the JavaScript file to find the features for me, or if I'm using the Resharper plug in, it actually does this without having the need to put this reference path in there. So the next thing we're going to do is I want to actually use jQuery to actually when the document's ready, I'm going to run this function here, and I haven't actually gone out and used jQuery yet. So I'm going to use New Get again. In this case, I'm going to go out, and it's always showing up in the (inaudible) downloads, or I can search for it. And once I install jQuery, I'll stick it in the Scripts folder. You can see it here. I can pop back over my home page, and then I can, in this case we'll just link in the jQuery minimized version. So we can see we got jQuery linked. We've got my own JavaScript of this page, and then let's also put the Knockout debug version in, and I want to use the debug version in this case in case I actually have an error so I can see the human readable form. Now we're going to type in the view model. So I'm going to type in a name for my view model. Let's call it My View Model here. And we'll crank it up, and we'll just put a first name property in, and hopefully my IntelliSense will work because I've got it hooked up, and I can see the observable property. And let's give this person a first name of John, and then let's do ko applied bindings and see if it shows up, there it does, for My View Model, and I'm good to go here. Now I should be able to get everything going. So I've got My View Model with a very simple piece of data in it, and I'm applying the bindings to the page. I've actually linked that to this page here, and I can see that it's using the text built in binding to display first names. As long as first name matches here, I should be good to go. Now one thing you may notice is underlining that the data dash bind is not a valid attribute for span. However, if you go up into Visual Studio, and you select HTML5 from the drop down list, that arrow will actually go away eventually, and then when I run this project here, I can click on view in browser, and we can see that the name is showing up as John, and we can check in here. Make sure there's no errors in the console window. None at all. I come back to Visual Studio, you can see the underline has gone away. So we can see very quickly this is very easy to set up Knockout in your project, and you can use jQuery if you like, or if you don't like, you can optionally not use jQuery as well. I like it because it makes things a little bit easier, and then when you're ready to go live, you can remove the debugged version, and just use the real version of Knockout for minified, which is just a smaller download. ( Pause )
Resources
John Papa: There's some great community resources that you can take advantage of when you're developing with Knockout, and I would highly recommend that you do so. A couple of these are Knockout js dot com, and, of course, up there, you can see the link to the source code over on (inaudible). There's documentation on Knockout. There's forms. There's some examples. There's also a series of tutorials that Steven Sanderson has posted up onto the Knockout site that you can take advantage of, too. And then on other sites, you've got things like Stack Overflow where there's a very active community of people asking questions about Knockout, or you can go to Ryan D Myers' bog. He's another contributor to the Knockout project, and he's written a couple of extensions and plug ins for it, but he bogs regularly at the Knock Me Out dot net website. And then, of course, jsFiddle dot net. Here's the link that you can get to for that. So let's take a look at some demos on how you can actually benefit from using some of these. ( Pause )
Resources: Demo
John Papa: The best starting point for using Knockout is go the Knockout js dot com website, which we can see here, and you can download, see tutorials, look at live examples, look through the documentation, go to the forms, or go to the source site on Get Hub itself, or you can just download from this quick link the actual source, too, and if you click on the source link, it's going to bring you over to Get Hub or you can through here, and you can look at different information, or you can download the entire branch using the zip file, or you can take a quick look at the js files themselves. Now if you go back on the page, there's other sites you can do, other things you can do as well like look through the live examples and tutorials. So, for example, if you looked at the documentation, we can see here, we've got an introduction, and over on the left, we can see how to create view models and observables. We see different bindings that you can create and other techniques. It's a very quick start to the documentation that you can use, but it's also very helpful for getting out of the gates. If you click on the forums off the main page, we're brought to the Knockout js forums inside of Google Groups, and you get there by clicking over here on the forum link. And then if you click on the tutorials, you'll come over here to the learn dot knockout js dot com, which was set up late last year in 2011 by Steve Sanderson and a couple other gentlemen to basically walk you through some of the basics of learning how to use Knockout. It's an interactive tutorial where it gives you different steps, and after each step, you can say continue, I've done the step, or help, it's not working. Then you can ask it to actually fill in the code. So if you can't figure out what you're doing there, it will actually help you walk through, and it's pretty really nice, and they'll save your state, too. The other link I mentioned was Stack Overflow where if you click into Knockout, there's a couple hundred different Knockout questions up here already that you can look at. So by clicking the Knockout js, we can see there's 638 questions that have been tagged up here, and a lot of people ask a lot of good questions that you can find the answers to. So very likely something you're already talking about might already be up here. If not, pose a question. And then off of the Knockout js website is Ryan D. Myers' site where he bogs quite frequently about Knockout. Here, you can see he's got some information about Knockout 2 coming out. And then, finally, I mentioned jsFiddle dot net, which is where you can fiddle around and create different JavaScripts in HTML scratch pads. ( Pause )
Summary
John Papa: In this module, we laid out the foundations for everything you need to know to get started developing with Knockout, with JavaScript, HTML, and CSS. We explored the current state of JavaScript development and how you can use good patterns such as separation using the MVVM pattern with Knockout to get started. We demonstrated how you can fiddle around with jsFiddle, how you can reference Knockout, how you can go get jQuery, some tools that you can use as well with Visual Studio extensions such as New Get, which I highly recommend you use to update your references. We also explored some of the key resources to help you get going with Knockout as well. In the next module, we'll dive a little bit deeper into Knockout and show how the different types of observables work with the different types of bindings that are available, and how you can customize some of those to get some of the effects that you need.
Bindings and Observables
Introduction
( Silence ) Bindings and Observables are at the heart of how Knockout (Inaudible) work. So in this module, we'll take a deep look into how built-in bindings work and the different kinds of observables that you have at your disposal. But first, we'll take a look at how you deal with pushing and pulling data without using data binding and without using knockout. And then we'll show an example with knockout so we can see the value prop that it brings. Then we'll dive into observables, which we've already seen a few examples in Module One, how an observable field, basically, a property like first name can notify the screen and then come back and notify back to the object. And then sometimes you need to have computed observables. What computed observables are, it's like you have calculated fields or, in some cases, converters, where you can read and write values that may not exactly map one-to-one from a property in a source object to a target on the screen. So we'll explore how those work. Of course, sometimes you have properties that are observables, and sometimes you want to have arrays that are observables as well. So you might have an array where you want to be notified on the screen when an item has been added or removed or even replaced. We'll explore what you can do with those arrays, how they work with knockout and different functions that you can do upon them. And sometimes you want to be notified when an observable changes. So you can actually subscribe to the change event of an observable yourself and perform some custom action on those as well. So let's dive right into these fundamental concepts.
Push and Pull Data without Data Binding
One of the keys to understanding knockout is to understand what its value proposition is with its declared of data binding. So let's first take a look at how life would be without using knockout to push and pull data. So in particular, here, we're going to take a look at manual pushing of data from a source object, maybe a JavaScript object out to your target, HTML elements, and then manual pulling back down from this chart of elements into your source object. Without knockout, you'd have to write code, basically, probably using jQuery to push your data up into the elements and then pull it back down. jQuery, of course, can assist us here but a code is still going to be required. And, for example, if we have 20 fields that we have to push up into the HTML elements and then 20 to pull back down when we want to press save, that's 40 lines of code you'd probably have to write in that particular case. Of course, there's optimizations we could do but we also don't get data binding notification. So when do you know to push? And when do you know to pull? It's not really true data binding. It's just that we're writing custom code for. Nothing wrong with it. It's just not automatic. So how does that work with jQuery? Let's take a quick small example here. What we're looking at is a guitar model and a guitar sales price in an input text box in HTML. Pretty simple stuff, so far. Now we have an object that we're going to load in the data from. So here's our source object called, Product. It's got a model and a sales price in there. And we're going to match those up with the HTML element. Using jQuery, we can just say, go find that ID, set the value of that to the product.model and then also do the same thing for the sales price. Pretty easy to do. We're pushing manually from the object up into the screen. But this code isn't going to satisfy what happens when someone changes the value of the sales price and presses save. We're going to have to write more code to actually pull that back down. So as you can see, we're adding a little bit more code. It's just to do some things that we could do, if we had automatic data binding, which is what knockout will offer for us. To really explain this, let's take a look at a demo. ( Demonstration )
Push and Pull Data without Data Binding: Demo
Let's take a look at how we can load data from a JavaScript into HTML elements and then back again without using knockout. So here, we have an example. We've got a JavaScript object called, Product, and that object is going to be pushed into the HTML elements using jQuery. So here, we've got a jQuery code. It's going to say, all right, go find the guitar item number and set its text property, basically, from the product item number, which is up here. So we're going to set it to T through 14CE. And then down here, we can see the guitar item number is a match; so that's going to be the span that's going to get set. And, likewise, for every other input we have, guitar model and the sales price, these other text boxes, they're going to get set in succession here from the jQuery code. So when we run this, it's going to push all the values up into the screen. So let's take a look at that. Here, we can see the values are pushed up first into the span and then to the input boxes. Now notice this is not using any knockout. It's just pulling the data's up from the JavaScript object into the UI. But when I change the values here, it's not going to get changed back into the JavaScript object. I need some code to actually pull that back out too. So let's take a look now on how we do the same thing using knockout. So let's say we wanted to add some elements down here. First, let's mirror the same elements that we have. Let's just go ahead and copy that. And this one will be with knockout. So with knockout, we're going to have the same elements but, in this case, instead of actually having guitar number be an ID, we don't really need that. Instead, we want to use the data bind attributes -- we have to spell them right, of course, -- and in that data bind attribute, we want to set the text property, the text built-in binding to a guitar item number. Now is that the name of the property that's going to be in the element up top? I don't believe it is. I think it's just item number. So let's go ahead and make that, item number. And then let's do the same thing for these other guys. So we got data-bind equals and then we want to set this to be the model. And then we have data-bind, and we want to set this equal to be the sales price. Now we want the properties of these to be value. That's the built-in binding we're going to use. So here, what we're saying is if, for this span, we're going to set the text built-in bindings item number for this input box; and this input text box, we're going to use value for model and sales price, and they have to match the same things up here; item number, model and sales price. So now we've got our bindings hooked up. But how do we actually take these and get them to work with knockout? Well, the next step is instead of using jQuery, -- and we'll just leave that code there, -- we just need to bind that product object to our screen. So we can use KO applyBindings and say, product, in this case, which happens to be our model. So now when we rerun this screen, we should see the same value show up in the bottom price. So here, we can see we've got the span, we've got the model, but we don't have the sales price. So what happened? Very likely, we spelled something wrong. So we've got sale price up there and, down here, it was sales price. So I had a binding problem. We can fix that quickly. And now we can run it again. We can say, in the browser the values match. So the point I'm making here is that we're loading the data up and pulling it back down using jQuery with several lines of code. In this case, we're only actually pushing it up to the UI's in jQuery. We'd require the same amount of code to actually pull it back down when somebody presses save, for example. So you could hook up a click handler and then reverse this where you pull the items back down. And then with knockout, all we have to do is we set up the bindings here. And then, with applyBindings, we're getting the values to push up to the screen automatically. Now one caveat with this example is that the fields are not actually going to have two-way binding with knockout because I did not define the (Inaudible) object as using observables. So when I change the values here from, like, a tailor of 134, choosing a tailor 914, -- which I'd love to have and at that price especially -- that particular name is not going to get updated back in the JavaScript object because I didn't define it using an observable. But we'll take a look at observables in the next demo.
Observables
Knockout uses observables to allow properties in a source JavaScript object to notify the UI when changes occur and, therefore, if the source object changes, every time it changes, the value will then be reflected on the UI. It also works in the reverse direction, if something changes in the UI to update the source object as well. But you don't need to use observable properties, unless you want the changes to actually occur in both sides. For example, you might just want to push values up one time when they're first loaded. In that case, you can still just use standard JavaScript properties. And then when you hit applyBindings in the code, it will actually push it up to the UI, as long as it's a data-bind attribute set in there. But if you want the observability, basically, the change notification to occur when that source object may change in the future or the UI might have a value change by a user, you want to use the observable function. The way you create an observable property with knockout is to create the property as KO.observable and wrap the value inside of the parentheses. So it's an observable function that creates a notifiable property when change notifications occur. This implements two-way data binding with your JavaScript objects to your HTML elements. So the way this works is, here, we've got the source object on the right-hand side where you've got tailor 110 in a property. So this is the value that's set for the model of the guitar property. And then when we use data binding and they're using an observable property, it's going to push tailor 110 up to the target element. Now let's say the user changes that value from tailor 110 to something like tailor 914CE of a different model. When that happens, that's automatically going to get pushed back down to the source object because we're using a KO.observable function. So we're getting two-way data binding here. And, likewise, if we change the source object again, it would automatically get pushed back up to the target element in the UI. In this example, we can see that there's an input element, and it's using the data-bind attribute, setting the built-in binding for value to product.model. This is declared of binding that's going to push the value back up to the screen. Now it's going to get that value from the model property, from product.model, which you see down here in our source object. The difference we've seen here, from the previous example, is that now we're using model to be of type KO.observable, wrapping the value tailor 314CE. So this model property is actually an observable, which means it's going to push the value up to the input, and then, if the user changes the value in the input box, it's going to push it back down to the product.model property. And, again, we use the applyBindings function to set this up. Let's jump right into the demo and take a deeper look at this. ( Demonstration )
Observables: Demo
We're going to open up the 2-02-observable HTML example in your solutions. And here, we can see, first, we've got a my.data object, which is going to serve as my view model in this case. We haven't talked yet about namespaces too much, and we'll definitely talk about those more in Module Three. But for now, just know that, my, when I see that here, that's just a variable I've created to define as an object literal. And we define that over in the script solver under data or as some sample data. Here, we can see, my, is basically just going to be an empty object. We're pulling an I namespace here. And I've got my.sample data. And all the data that I use in this particular chapter is going to be using sample data. So here, we've got my.data. In this case, we're using a view model called, Data, and it's got a metadata property as well. And all my examples, I'm also going to have a metadata property object, in this case, which is going to have properties for the title of the page and then personal information like link in the text. So when you run these examples, you're going to see -- up on the top of the page, you're going to see the information for the metadata. So when I search -- click on observable, you can see up here, there's the metadata, the title of the page, the index link and then the link to my (Inaudible) account. Coming back over here, we can see we have another property called, Product One. Now product one is a mirror image of product two, except for one thing. Product one, I'm defining the properties without observable. Product two, I'm using the observable. So in this case, now I've got two different products, same product, but two different product objects that I'm using to do my data binding. And I'm also going to applyBindings on everything in my.data to my screen. So we can scroll down and take a look at our HTML. We can first see that we've got the object literal up here, where we're going to be displaying the information from product one, which is not using the observable, and then we're going to be displaying the same values below it. So we're displaying the values twice, because, on the top, we're displaying the input boxes. We can change the value. And then in the bottom here, we're going to mirror image those using span. So the idea is when I change the value in the text box, hopefully, we'll see that if it does or doesn't change in the span below it. And then right below that, we're going to do the same thing but this time using the observables, which are in product two. So the top two basically mirror image product one. The bottom two mirror image product two. And the code here is the same. It's just product one versus product two. So we can see the demonstration of is it going to update the objects form me? Now here, we've got on the top the object literal. I've got tailor 110. And when I change this value, notice down here it says tailor 110. When I change this value to tailor, let's say, 9000, the value is not changed down here in the guitar model. When I change the sales price from 699 to 2699, it's not changed because, in this case, we're using product one, which, again, back in my code, product one was not using observable. So those values are not being updated. Now I want to do the same thing down here. And I change it from a tailor 314 to a tailor 814. Notice it automatically changed down here in this span as well. And if I change that price to something like 21,000, in this case, the sales price is updated again. So values are going into this input are going to go back down to the source object and then back up to the span, in this case. So here, we can see the two-way data bindings happening with the bottom fields because they are using the KO.observable. You're probably familiar with the concept of observables, if you've already done .NET development with XAML such as with Silverwhite or Windows Phone 7. Because, an observable is basically the same kind of analogy as using an INPC interface, the INotifyPropertyChanged Interface that .NET offers, which allows its properties to automatically update and send notifications when something changes in an object's property and then also to receive those changes back down the chain. In this case, knockout is just using that term, observable, to mock all of its properties up here and wrap them inside an observable function which will then notify the UI and then also accept changes back. And this is what enables two-way data binding.
Computed Observables
Computed observables are properties that are dependent upon each other. So they're computed recalculated whenever other observables change. This comes really in handy when you have things, like full name, where you want to calculate a first name plus flat and last name equals a full name. You can also use that for photo URL's, where you've got a hard-coded value and you want to -- can catenate that out to a URL next door or in some kind of a JavaScript object, or you can also use it for calculating totals across one object or multiple objects. Whenever the observable changes that the computed observable is using, it automatically notifies that the change has occurred so that computed observable will then update the UI in that case. And one thing, be careful when using computed members, is that there's the, this, keyword that (Inaudible) use in JavaScript, and you got to be careful that you know what the, this, keyword is going to mean. And there's a way that you can actually make sure you know what it's going to mean, by passing in the owner parameter when you use a computed member. The computed is formally known as Dependent Observable. So in knockout 2.0.0, there's a new type of operation called, Computed, which is basically synonymous with a dependent observable. So if you're using older versions of knockout, it's called, a Dependent Observable. In the newer version of knockout, that still works. But the new way to call it is a Computed, which is a little bit easier to say. So here's how you define a computed member. Up top, we've got a view model, and we've got three different observables that we have. Now we may want to calculate the sales price times the quantity, and we can call that extended price. So how do we do that? Here, we can say, on the view model, we'll create a property called, Extended Price. And we're going to define it as a KO.computed. And that's going to be evaluated as a function that returns the value basically of the product, where it's going to say this sales price times and then it's going to parse out the quantity and calculate it for us. Now notice the parts that are bolded here. First, we've got two observables that we're pointing at. We've got the sales price. This is an observable down here being reused again. I have to use the keyword, this, here, just to make sure that this is referencing the view model. I pass in the view model as the owner. So down here, I'm saying, all right, the optional parameter view model, this is going to take the representation of this; so then I can just say this.sale price. I'm using that again for the quantity as well and for the product. So with that, let's take a look at how we create some computed observables and see where they could really become useful.
Computed Observables: Demo
Here, we're going to create an observable property that's going to calculate the photo URL for the photo to show the guitar and another one to actually catenate the extended price. We can see here we've got the photo path, which is hard-coded to a path where all the images are located. But now we need to create a photo URL. So we're going to extend our view model object and create a property called, Photo URL. And here, instead of creating an observable, we're going to create one called, Computed, that we can use, and we're going to put them up here and create a computed function. And we're going to get that function, an expression that's going to calculate out the photo path. So we're going to use the photo path here, which is a variable we already have, and then we're also going to use the photo property, which is an observable that we have up above. Now what we've done so far is just saying, all right, take the photo path and you can catenate it with this.photo, which is up here. And we're assuming that this value here has the URL that's been stored and then represented for the picture. Now that's not all we have to do. So we make sure that this is actually properly represented. We can pass in this as part of the owner here, which actually makes sure that this is being passed in, will represent this. Not as useful in this particular case. But if you wanted to make sure that the view model is represented, you could just pass in the view model right there. So that's going to get us the photo URL. So let's go ahead and copy that. And we'll come down and look at the HTML. The bottom of the screen, we see an image tag. And here's the attribute binding. And we're going to set the source equal to product photo URL, and he's good to go. And making sure we've got our commas in the right place, we'll slide over and take a look at this. So once we've got that there, now we know that the photo URL is going to be represented. It's inside the product and then as a photo URL. But we also want to add an extended price down below. So we've got the unit price and the quantity. Let's say we wanted to add an extended price. So here, we can create a new div. Inside of that div, let's put a span, and this span should represent the extended price. So we don't have a property for this yet, but let's go ahead and just data bind it with some text equal to -- oh, let's go ahead -- and let's not put it in there. Let's call it extended price and he's good to go. And then we also probably want to have another span at the beginning just to say what this thing is. So we'll put a span at the beginning that just says, all right, this is the extended price. And we'll give this a class because that's what all the other guys have, and we'll set it to be caption. So right now we've got this property called, Extended Price, which we have started to use, and we want to go create it up top. So in this case, we're going to extend my view model. And the way I know it's my view model is right there. It's my.view model. And then I'm going to say on that view model itself, I want to create a property called, Extended Price. And this is going to be KO.computed. And inside of there, I'm going to say function and then create the expression itself. I'll go put on the semicolon at the end. And I know that I want to pass in the owner this time because I want to make sure that the owner is actually my view model. So inside of here, I want to return. Now this is going to represent my.VM. I want to return out based upon this expression; product, if it exists, I want to go ahead and say, all right, take the product and get it at the sale price. And let's multiply that by the -- well, we better parse out. So let's do a parse in. And basically, we're going to take in a zero first. And let's just bring this down to another line so we can see what's going on. And we can take in a zero and we'll take the, this quantity, and we'll put a 10 there and we'll make sure that we've got an out. And if not, if there is no product, we're going to return a zero. So basically, we're just using a parse in to create the -- to parse out the value for the quantity in case somebody types in the value other than a number there. So right now we've got an extended price observable. And every time, this computed is going to be calculated every time that the sale price or the quantity changes because it's relying on those. This is what a dependent observable and many means. And down here, we actually called that value extended price, I hope. Yep, there it is. So we should be able to view this quickly and see it in the browser. And we can see that there's the calculation. We'll do a simpler math here. If it was five bucks, unit price, quantity was Ford, the extended price is 20. So we can see that's calculated very easily in a read-only fashion. So this is how you use the computed observables to create read-only values.
Computed Observables on an Object Graph: Demo
Computed observables can do quite powerful things. So let's take a look at another example using a computed observable to actually calculate multiple line items in a sales order and then calculate the total. We look at this example here and we can see the grand totals. As we add products, we can see that the first products appear with a quantity of one and the total values is (Inaudible) up. Well, when I add another product, and I'll select baby tailor, and we add three quantity in there. Notice that the calculation is being used up here for that as well. So as I type this value in, -- let's give it 33 -- we see the extended price is over here. This is the computed we created earlier. And down below, there's a grand total computed. Let's take a look at how this grand total computed is being calculated. So right now we've got the computed being defined as grand total on my.view model and that function is actually going to be using jQuery's each to iterate through all the lines in my view model. And then for each line, it's going to calculate, all right, take the extended price and add it to a variable called, Total. So for every line, it's going to calculate and keep accumulating the totals and then return that total amount. And that's what's going to be representing the value of grand total. Now I jumped over this real quick here on purpose. The, this, keyword, again, is being used to represent the view model. How do I know it's my view model? Because I'm passing that in as the owner parameter of the computed operation. So my view model is represented with, this, in this particular case. Now there's other ways to use, this, no pun intended. So there's a couple of ways you can do this with computed. Now we've got some computed's here. Notice we've got the computed for the extended price. I'm not actually using the, this, keyword. I'm not actually passing in the owner in this case. I'm using self. Now self is a variable I've created. It's just a convention. And it's using a lot of JavaScript. Here, we can see that inside the function, I'm setting self equal to this. And then I use self inside of the computed so I know what I'm actually referring to. That's one way to handle this with a computed observable. You don't have to do it this way, but it's one option. If you'd like to, the second way you can do that is to pass in the owner right here. You could actually pass in whatever your context is for the view model. So we could do that as well. And that's what we're doing down below when we have our grand totals. We want to pass in the view model. I tend to like this particular technique because that way I'm always being explicit on what that particular view model is going to be when I use the, this, keyword. So once again, as we come back over here, we can keep adding products. And as we add those products, we can see the calculations will automatically accumulate. And as we remove products, they will also decrease. And this is just another way to use computed observables.
Writeable Computed Observables
Knockout's computed observables don't just work for reading values and calculate them. They can also calculate them back when somebody writes a value for them. So this is great when somebody wants to allow binding a custom computed observable up into the screen. And it allows me to change it in something like an input in HTML and then write it back to the model. So in this case, you would define a read function to read the value and to calculate it to display on the screen; a write function for them when somebody changes the value in the screen to parse those values out and store them in one or more observables in your model or view model, then, of course, the owner to specify where the view model is, which is optional. A great analogy using these is if you've ever written converters in XAML or .NET technology. They're very, very similar in this case. But it's very powerful because you can write read and write. Basically, you're converting from your view model to your screen and then from your screen back to your view model. This is really great for a lot of different situations, which we'll take a look at in the demos in a moment. ( Demonstration )
Writeable Computed Observables: Demo
Knockout's computed observables don't just work for reading values. You can also calculate values as you write them back to the store as well. So when you're reading values in using a computed, you can calculate like an extended price and display it on the screen. And you can also make that element that's on the screen be like an input text box; change that value and then parse it back out using a computed to save it back into the JavaScript object. Let's see how that's done here. First of all, we want to run this particular screen and see the scenario. Here, we have unit price and quantity both stored in observables. And when I change the unit price to, like, $100 and I have the quantity as 2, I'd expect the extended price to change. And then also when I change the extended price, I want it to automatically write back to the unit price. We'll leave the quantity alone. Basically, assume that if somebody changes the extended price, it's going to automatically divide by the quantity and set the unit price. So let's set this up real quick. First, down here underneath this span for extended price, I want to add in an input for the type text box, and I want to set a data binding attribute up. And for this, I'm going to put the value in to be a new observable. I'm going to create, called, Extended Price. This is going to be a computed observable. And I'll also stick in here the value update for, after key down, just so I can type it and be done with it, as we go. And that will automatically set that up to be the binding. Now up top, we want to create the observable on our view model. The view model is called, My VM. So we'll take My VM here and we want to create a field called, Extended Price. And I'm going to set it equal to be a computed that we can have here hanging off of the view model. Now normally, computed, we'd set it to be a function, but, in this particular case, we don't just want to be able to read values. We want to write them. So we're going to use the more extended syntax and pass an object literal in as the parameter. This object literal has a couple of different values. First, is what do you want to do when you read the value up? This is what's going to be -- this is (Inaudible) when we pull values out of the JavaScript object up into the UI, what's going to happen. That's going to be the function that actually does that. So that's my read. And then I also want to have what happens when I write. So in this case, we're going to have a function here. And the function is going to need a value parameter, because this value is going to represent the value that comes out of the UI for the binding so we know what to do with that particular binding value. And, of course, we've got the owner, once again. And the owner is going to represent -- is going to be what is represented by the keyword, this, inside of the functions. So we want it to represent the view model. And this puts us a nice little scenario. We've got everything set up to go. So out of the gates, we want to be able to calculate the extended price. Instead of typing it all out, we seen this logic before. So I'll just type it in here. I'm going to say get the extended price as being, if there's a product, calculate the sale price by the quantity. And this parse in is going to become very important because we're actually going to be parsing out any decimals or any dollar signs later as we write the values back. So if you look at this real quick, -- let's just get rid of the write for a moment -- if we look at this real quick and load it up into the screen, we should see the extended price show up. Now I changed this extended price to another number and nothing else is happening. This is where the write will come into play. So let's put the write back in. And here, we want to write the function that the write's going to do. Now first, we want to strip out any characters that we have in there and parse out the float. So we've got that value, and we're going to reset the value by parsing out the float. Make sure we actually have a number. And as long as we do at the end of these two statements, we've done some reasonable error checking. We should have a number value. Now we want to store the actual calculation in a new field, a temporary field down here called, Unit Price, which is just a temporary variable, and we divide the value by this.quantity. Remember this is the view model. So we've got this.quantity, is the quantity field; that's an observable on my view model, which we can see up there. The next step we want to do is actually take that calculation and store it right in the observable for the sale price because we're calculating that value, and we're going to set it to be the sale price here. Now we could have done all that in one step or actually combine all these too, but it makes it a little more readable to do this. So we're pulling out the values that's in the screen. This will be on the screen with the dollar signs and the decimals or anything else in there. We're going to parse out those values, get a value, divide that by the quantity, and then assume that quantity is valid and have the unit price, and we'll set it to be the sales price. So when we run this, we now have the text box down here again. And when I change this value from 8000 to let's say 78,000, notice the unit price is immediately updated. When I change my unit price to $200, the extended price is automatically changed as well. I can get rid of the dollar signs here, and I can type in $7400. And this is how easy it is to use computed fields to do reading and writing. ( Demonstration )
Observable Arrays
Knockout also has support for observable arrays. So instead of just having support for notifying changes on a particular property, we can have an array of values. And whenever a value is added or removed from that array, it's going to notify the UI. And the way these work is, basically, it tracks the objects in the array. It doesn't track the state of those objects. So you might want to have an observable array containing observable properties on the object itself, if you want to track the state of those properties inside of it as well. What it does track is when items are added or removed. Add there's a whole slew of functions that you can use off the observable array. And we'll demonstrate many of those. So how do you set this up? Here, we have a view model with two different observable properties and then we have an observable array which contains objects here, which has got a property for a model and price and ID. Notice these properties are not observable. So these properties themselves, when they change, they won't notify anything, not the array and not this particular object. But when items are added or removed from this products observable array, it will notify the UI or any bindings that it's listening to. In this case, it will be bound to this span here, maybe. And the span can say products length. And any time a product is added or removed from the observable array, the length of the update, and, therefore, it would show you how many products are there. So here, we're pre-populating the array. And you can also add that at runtime as well using the push and pop features or some other functions on the observable array. And there, we can see how we can operate on the observable array itself. So let's take a look at the demo on how we can use observable arrays, because there's quite a few reasons to use them and a lot of different ways that they can really enhance your app.
Observable Arrays: Demo
So let's take a look at the example here called, 2-07 Observable Arrays. And we can see that in our view model, we've got a property called, Products, which is a type of observable array. And by default, it's set to an empty array. And then we've got a function here called, Load, which is using jQueries each to go through and iterate through the sample data that we have that's over in our script's folder. And here's our sample data that we've got. It's going to iterate through all those products, and it's going to load them up into our products observable array. And each time it sees one of those, it's going to push using a push function on the observable array, a new instance or product, and it's going to map in basically the ID, sales price and other properties into that particular product. Now the new product is up here. So I'm actually creating a function, a constructor function here where I can pass in the values, where I can say, all right, set ID equal to be observable, all these properties are observables themselves. They didn't have to be in this particular example, but it's just showing you one way you can create a constructor to do so. So once I call load function, which I'll do right before I apply bindings, it's actually going to load up all of my data into my products observable array. But where do I put this? So let's load this into a select option down here. Where I've got my select, it's multi-select. But what I want to do is actually do the data binding to load up my observable array. So let's move down to another line so we can see everything. We'll enter in the data bind syntax. And here, we're going to load in the options, as we saw earlier, and I want to bind to products. Now because we're binding to products and it's an observable array, as soon as the items are added or removed, it's going to load into this selection. And we also want to track which item is selected. So we'll set the selected options equal to an observable that we'll create called, Selected Products. And we want the options text. Since we know that each product is actually a object itself, we want that to be showing the description. Now we didn't set the options value because we want the options value to actually work out for this selected options in this case because it's a multi-select. So that should load those guys up. And because we have selected options going on, we should come up to the top here, and we probably want to enter in the other properties that we'll need to track, what's been selected, for example. So in this case, I think we called it selected products and we'll make that a KO.observable array and make that array. And by default, that will be empty as well. Now the reason we're sending this guy up is because we want to track which items were selected. So right now we don't have a whole lot of functionality, other than we just have the products being loaded. They're bound to the selection and then they're going to -- when they're selected, they're going to be entered into this observable array as well. Now let's add some other functionality in here. So here, we have a products title in this span. For the products title, let's put how many products there are. So let's put a data bind syntax up here. And we want to data bind this expanse. So I want to use the built-in binding for text products length, and that's going to put the number of products that exist right here in this span up top. Now we've got our selection box. And we could add some other functionality for removing and sorting and adding in a moment. But first, let's make sure we have a running example. And we seem to. Let's check the debugger here. Nothing in the console window. Here's my 14 products. Notice it shows me the length of that particular observable array, is 14, and I've got all my items in here. Now my removes and sorts and adds aren't doing anything yet because I haven't put any functionality behind it. But we can fix that pretty easily. First, let's add the remove functionality. We've got a button here, and we want to set some data binding for this guy, and we're going to want a click event on this button. We'll do remove selected. And also we don't want to enable this guy, unless products are selected. So let's create a new observable called, Products are Selected. And we'll handle the remove. So let's do that now. We'll go up to the top now. I've got to place a code here. We can actually add in the removal code. We have, products are selected. So we can create this property up top here. Now we can make this a regular property or we can make it an observable. What we really want to do here is make this a computed. So I'm going to copy in some code. And the reason we're doing this as a computed is because we want to track to say, all right, how many items are there in there, if it's greater than zero. We're going to return true. Now I'm just showing you one other option with the, this, here. I could have passed in the, this, for -- or sorry -- the, my.VM, for the owner. But I'm just showing you one of the way to do so. I can actually just use it right inside of the computed as well. It's just an alternative. Instead of passing the owner, which means I could have done that like this and go in and type this. But I decided to just show you one alternate way to do it. Now we track the products that are selected. We also need to have a function on the view model called, Remove Selected. I think we selected or selected an item. We'll take a look. And it's a function. And then we also want to set that function to actually remove the item itself. So we want to go in to the view model and we're extending the view model; so we're going to say, all right, go see the products. There are some functions built into observable arrays to make it a little bit easier for you to remove. We can say remove all. This might sound a little funny at first. We want to remove all of the selected products that we have. So it's going to go out and get the selected products off of the view model and remove them. And then when we're done, we're actually going to reset the selected products because we don't have anything that's selected after we remove them. So here, we're removing all of the items that are in the selected products. This is why we did the data binding, for selected products, before. And we view this guy now. We should be able to come up here and do multi-select and we'll get rid of a couple. There were 14. When I do remove, now there's only 9 left. Notice the remove is now grayed out. It's not enabled, unless an item or more is selected. So I can remove a bunch of items. And all it's doing is removing it from the observable array itself. Next up, let's add the sort functionality in place. Sorting is pretty easy to do. You can write your own sorting function, if you want to. So let's go down. And we've got a button for sorting. And let's add the sort buttons data binding. And just like we had a click for -- just like we had the click built-in binding earlier for the remove, we're going to create a click event here; click binding for sort products. Now when don't we want to sort? If there's no items in there, we don't want to sort at all. This is where we're going to do the products exist, and we're going to create a observable that's going to track if products exist or not. Because if they don't exist, we don't want to be able to click the button for sorting products. So that's pretty easy to do. So let's come up here and let's add some code for sorting. Here, to save time, I'm going to copy and paste the solution for the sorting in real quick and just walk through what we're going to do. Now first, we have a pretty easy example of a computed up here, products exist, to make sure we actually have products before we actually sort. And then we've got a sort products function, which is a standard function, and this is the one that's bound to the click built-in binding. And here, we're actually using the sort method off the observable array and that's built-in to allow you to pass in a custom function, like left and right, where it passes in the left value and the right value, the two values are going to compare. So you're writing your own comparing. And in this case, we're comparing the description fields. It's my own choice in how I want to sort them. And you notice I've got a description field on my property up here. And I'm going to compare them alphabetically. So just writing a poor man's version of a sort, I'm going to convert that to lowercase and check to see if it's bigger than the right description. And I need to return zero, 1 or negative 1, based upon which value is greater than or less than or equal to. And then that's going to be return and that's how the sort function is going to work. So again, this is bound down here to the click event. And when I run this code, we can see I've got my values up here. And I can sort because there are items. So it's enabled. And when I click on it, notice tailor is first up here, the tailor 314. When I resort, the Dunlop is the first one in the list. So we can also go through here and add different items. Let's take a look at how that works. To add an item, first, we're going to need a text box, which, luckily, we have down here. And we're going to add a data binding in so we can know which value we're going to add. And we'll use the built-in binding for value. And we'll have to create an observable for item to add. And we can automatically update it as well using, after key down. Once we get that binding in place, this time, instead of using a button that's going to -- use the button click, we're going to use a submit button. So up in the form itself, let's actually data bind to a form. So if you're using forms, you can also use data binding. There's a built-in binding here for the submit to work with add item. We didn't cover this one before because it's so similar to the click event. In this case, it's actually working in binding the submit button down here. So when anything inside the form is submitted, it's going to automatically call the add item method up there. But we do want to put some data binding on the button itself. For example, we don't want to enable this if somebody hasn't entered a value in the text box. So we'll use the enable built-in binding, just do, item to add and get the value for it where the length is greater than zero. So if this item to add, which is the key here, has a value in it, we're going to enable this button. Then when we click on that, it's going to call the add function that we have up top. So -- but first, we need to add the item to add as an observable property, and we'll set that to be nothing, by default. So that's all good to go. And then we have to add the adding functionality itself. And adding code is pretty easy to do. We can use pushing and popping, which are built-in functions on the observable array, and that's pretty easy to do. So we'll come up here, and I've got a place to put the code. We're actually going to just paste it in real quick. We're going to say add item as a function. And first, we're going to do some quick checks to make sure there's no blanks in there. And if so, the key here is we're pushing into this array, this observable array, a new product. And I'm kind of being lazy here. I'm only actually pushing in the description value. I could push in the item number and the sales price and everything else as well, but, really, all I want to do is I'm only -- have a text box that has a single value for item to add, in this particular case. I'm going to take that value, load it into description, create a new instance for product and push it to my products observable array. And then after I'm done, I'm going to clean up that text box and blank it back out. So we can see now when we run this example, I could type in a value. Notice add is disabled. When I type in a value for a new guitar in there, like a Martin, as soon as I start typing, the add is re-enabled. And when I click on that, it says 15 products and I can go search for it or I can sort, and notice the Martin shows up right here. So as you've seen here, it's pretty easy to add a lot of functionality using observable arrays, and there's quite a bit more you can do as well, as we'll see in just a moment.
Observable Array Functions
There are several functions that are built into knockout to help you with observable arrays. Of course, you can write your own too. We've seen earlier, we saw the push, where we can push a value into an observable array. And there's a matching pop, where you can pop an item out of it as well. We also looked at the sort, where you can pass in a function that you can sort the array by, or you can use just a standard sort, if it's like a string array. But they've got a couple others too that you can take advantage of. We can deal with the index of to find a particular item, maybe it's a returns the index of that item. We talked about push and pop, where you can pull items in and out of the array. There's also remove. You can remove a single item or remove all or you can remove array of items from the observable array, like we did with these selected products, and we select a multi of them in the previous example. Here's a reverse that you can use, where you reverse the order of the array. Then we've got a couple others as well such as shift and unshift. Now shift is going to remove the first value from the array and return it. So it's kind of like a nice way to pop it out of a queue from the first item in the array. The unshift is allowing you to insert an item at the beginning of the array as well. So you can unshift one by putting one in front of the entire array. And then we've got the slice and splice functions that you're probably pretty familiar with, if you've done any JavaScript. So the splice function is going to allow you to splice the array and insert a value or remove a value from its particular place. And you've also got the slice, which is basically just the equivalent of the (Inaudible) JavaScript slice function. So let's take a look at an example that shows you how to use all these functions on observable arrays.
Observable Array Functions: Demo
Here, we have several of the different observable array properties and functions that you can use to operate on them. We mentioned that there's some, like pop and push, that we've seen earlier in sort. We can also do things like splice or replace. Now replace is something really handy because it allows you to replace an item in the array with another item. You can splice array values. You can unshift or shift them. And in this particular code example, which is already coded up for you, you can see it's called, 2-08 observableArrays functions. When we run this, we can see all the different values here. I've got an array of four products; guitars, capos, straps and pics. And I've got the remove and sort, like we had earlier. Let's say I want to reverse the order of these though. It will automatic reverse the order for me. And then I can do a push here. Let's add something else in here, like a drum set. And I can press the enter to submit. I can do splicing on here. So this is going to insert an item before the first selected item. So I've got to select an item here called, Capos, and I want to add something in here. Let me add in something, like a trombone. I can insert that before the selected item, or I could replace an item. So let's replace capos with something like really big flute. And we can replace capos with really big fluke. We can add via unshift, where it's going to insert at the beginning of the array. We can type something in here, like, let's say, harmonica. I'm sure I'm spelling that wrong. It goes up to the top of the array. And now here, we can use shift instead of unshift to remove the first item in the array and return it, and that's going to remove the harmonica in this case. And remove it via pop, which is going to be the last item in the array and return a true (Inaudible) drum set, in this case. Now all the code for these particular functions are written down in here, in this sample that I wrote for you. So you can take a look at how these work and examine them. They're really not that hard to use. As you can see, it's mostly just calling the observableArrays function and then passing whatever parameter that it needs. And the remove here is set up for you. The only one of these that's not documented on the Website for Knockout, if you go look for the documentation, is the replace, which is actually a function that's in the Knockout Library, but it's not documented. I find it very handy. Now if you don't want to use the replace function, you can also actually use a combination of the splice and slice, if you want to use the splice to replace an item and then insert a new one as well. But it's just a hint for you to use as you're going through creating observable arrays. I find these functions very valuable and I know you will too.
Subcribe to Observables
Knockout has a variety of observables, as we've seen. We can attach them for properties. We can create them as computed. We can have observable arrays as well. But sometimes you want to be able to subscribe to a change that isn't automatic through one of the standard built-in observables. So one thing you can do is you can actually subscribe to a change manually, and that's using the subscribe function. This can be really handy when you've got a situation where you need to subscribe to a change and it's not built-in to one of the other observable property or functions that are in knockout. So how do you do this? You can register it to be -- notify when a change occurs. It's kind of like setting a writing code for a property (Inaudible), if you're doing .NET code as well. And what you do is you go under view model onto a particular observable that you may have. So we're assuming here that selected make, in this example, is actually an observable, and we're subscribing to the changes. So subscribe is basically saying, all right, I'm going to hook into when the change is actually happening, run this custom function that I have. So I'm saying here, when somebody calls and changes the selected make observable, maybe a make for a car, for example; so like, they change it from Toyota to a Honda. When we have that and we subscribe to it, this function is going to get called and say, all right, now take the view model, selected model, and set it to undefine. So let's take a look at a demo here that shows you how to do subscriptions and where it can really come in handy.
Subcribe to Observables: Demo
In this demo, we're going to open up the 2-09 subscribe link drop-down list that you have in your solutions, and we're going to look at this. And basically, we've got a set of linked lists that are set up for cars. Now here, we've got a list of cars, like Lexus and BMW, and we can see there's two items in that list. When we select that, it's going to select the filter down the list of models. We can choose Z3. There's three shown. When we choose Z3, now we can see there's a 2012 yellow and a 2009 red that we can choose, and it's binding to the selected make, model and car down here. Everything looks great. However, what do we want to have happen? What's the behavior that we need if we unselect a model or unselect a make? If we change the make from BMW to a Lexus, we're okay because it resorts everything for us up here. But notice down there, the selected car still says 2012 yellow. That's not what we want. Also let's say we go and choose Lexus here and then at the top we choose a make again. And again, we're seeing that these values are still bound, so is the list of cars. That's totally not the behavior we want. It looks like we've got a lot of work ahead of us. But, thankfully, due to the way that subscriptions are set for manual subscriptions, we can actually take care of this pretty easily. Before we solve the problem, let's take a quick look at the code that's in here so we understand what we're facing. Here, we've got a car object. So we create an instance of a car. We've got all these observable properties, like the description. That's where we end up having the year and the color. That's why we had 2012 yellow for the cars. And then we have a set of sample data here for all the makes, all the models and all the cars and they're linked through keys. So here, we can see that the BMW is Key B. And then down here, these are the three makes for those BMW's with Key B. And then likewise, we have those for the colors down below. And then once we get those, we put them into the view model itself. So here's all the makes. Here's our selected make, model and car. Notice those are observables and they're to blank, by default. And then down here, we've got a computed that we're using to set up the list of models. And we're basically just filtering out the list of models for the selected make. And if there isn't a selected make, we return back null. Likewise, we've got a computed for the cars. So these -- this is why all those boxes are working on the screen when we actually select an item. When there's a value in there, things are all great. But what we need to do is to figure out how do we handle it when there is a change, like, we select the null item back up in the top list again for the make. So we're going to subscribe to -- when the selected make changes, we want to know. So if that selected make is changed, we're going to call subscribe. And that's actually in knockout itself. And in that subscribe, we're going to pass in a function. And we're going to define this function on-the-fly and say we want this function to do is, all right, go into our view model itself, and we're going to set the selected make to undefined. So when that make changes, we're going to select the -- actually, we want the selected model. We don't want to get recursive craziness here. So we want to set that equal to the undefined value and then we're going to pass in my view model over here, and we're good to go. So what we've got, in this case, is we've got selected make, a subscription; so the make changes. So if someone changes from Lexus to let's say nothing, we want to take the selected model and automatically set it to undefined. And because that subscription is there, it should wipe out that first box for us. Now we have to do the same thing for selected model, because, if somebody changes the selected model, we want to know so we can reset the cars as well. So down here, we've got a selected car and we're going to set that to undefined too. Now simply adding in those subscriptions, should solve the problem for us. Let's refresh the page. We choose our make. We do the happy case first. We choose Z3, 2012 yellow. Now I go back up to BMW and choose a make again. And notice everything else gets unbound because of those subscriptions. This isn't a scenario you're going to run across all the time. But when you do run across it, it's a pretty easy thing to solve. And you can put in any custom code you want inside of that subscription. Now it's worth noting as well that if you'd like to take that subscription and you want to unsubscribe later, one way to do that is you could say -- let's go ahead and return the value of my subscription, in this case. And then later on, you could say my sub. And then you could call the dispose method and that will actually unsubscribe from that subscription later on. So we don't actually want to do that in this case. But that's one way that you could do it. ( Demonstration )
Summary
In this module, we demonstrated the different ways that data binding works with knockout. First, by showing you how you can do data binding with push and pull mechanisms using JSON and jQuery and then by going through the different ways that knockout using observables, computed observables and observable arrays. We also demonstrated how you can use computed observables, formally known as dependent observables, to do read write conversion as well, similar to what you can do with the XAML technology with converters. And then we wrapped up by discussing how you can do subscriptions to changes as well. So if you don't find that observables or observable arrays are working for you in your particular situation, you can actually manually subscribe to the observables to get change notifications to handle specific events that you need to get to. In the next module, we'll be talking more about bindings by going into the specific built-in bindings that knockout supports. ( Silence )
Built In Bindings
Built In Bindings Overview
Knockout has many built-in bindings to help observables basically bind themselves to UI elements in HTML. It's a level of indirection that basically, allows the Knockout library to bind a value to let's say, a spans text built-in binding and not have to worry about what the user to figure out if it's inner HTML or innerText or what attribute on the element we need to bind to. So we've got the value and the text bindings. We've already seen the value we saw on the input and the text on the span, but there's many other built-in bindings as well. This is just a way of facilitating the bindings to different attributes for elements without having to know all the attributes on the elements, especially, since there might be different ones on different browsers of different DOMs. You can also combine multiple binding expressions with different built-in bindings separated by commas. For example, here we can see an input textbox and the data binding attribute is saying, set the enable built-in binding to allow editing, so there's some property on a view model that's going to be bound here, this is allow editing. And it's going to either enable or disable this particular input. And then set the value for that as well to sale price. So this way you bound two different attributes of the input using enable and value built-in bindings. We don't have to figure out which of those attributes are on the element; Knockout will do this for us under the covers. The dropdown list is going to have its options loaded from the list of color objects. And then we're going to have the value that's has been selected to be stored in a selected color property. And then all the objects that are colors are going to use an option text for a property called "name" and an option value for property called "key". So you can see where we can combine multiple different built-in bindings into a single HTML element. And there's many, many other built-in bindings as well. For example, we've got the click and the event bindings. The click binding will allow you to bind, let's say, a buttons click event or an elements click event directly into the HTML. So you would say data, dash, bind, and then say, click, colon, and then bind to a method under view model. The event bindings, a little more generic allows you to bind to any event that you want to by specifying the name of the event, as well as the method you want to bind to. There's also different binding's for displaying and enabling and disabling values and Unibindings too. So we've got the disable, enable, and the visible bindings which are pretty self-explanatory. You can disable or enable the items. There's also of course, the text and value binding which you've seen previously. The text ones used most often with things like dibs and spans or labels. And then the value binding can be used with anything of type input, for example. It could be used as something for an input textbox or maybe checkboxes. And sometimes you'll want to bind if it's some property that isn't specifically cradled with a built-in binding and that's where the attr built-in binding can help you out. This is very useful for doing things like binding to a URL for an image or some other attribute that may not have a built-in binding automatically. Now the value binding is very special because it has a couple extra features that you can take advantage of. So once you define a value binding, let's say an input textbox, by default all the input values are going to be updated, bound to the observable property that it's bound to when the input areas value changes. So in other words, when somebody types in the name John in the textbox, and then tabs out of it, on the tab out on blur, it's going to update the observable. That's the default. That is the change out value for the value update. And the way you specify that is to say input text, data bind equals value price or buy into the price comma value update is after "key down" or change, or "key up or key press." The default is on change. After "key down" is another column that we use a lot. And that's when the key is pressed once. You can also do key press, which is the key is pressed and it's held down. That's actually going to update every time or on "key up." Let's take a look at several examples that show you how to use these built-in bindings.
Bindings: Text and HTML: Demo
We're going to start by looking at a couple of built-in bindings at a time. Here in this particular one, we're going to look at the text in HTML bindings first because they're going to display just information, usually in a Read-Only format, generally. And then we're going to take a look at other examples that display all the other types of built-in bindings. So each example here starts with 2 dash 3 and there's a letter A through I. We're going to start with the text in HTML, which you can see here, and let 's first, just run this and see what, happens. When we run this guy, you can do it View in the browser. We can 'Save' at the text binding up here. Well, if you've seen this before in the samples, where we're just binding to expand using the built-in binding for text. And we also have HTML down here, where it doesn't look like HTML and in fact, we're actually just binding to text here too. So let's take a look at how this one works and we can see what's happening. We can fix it to use HTML. So in our JavaScript we can see we've got a property called Details here and it says, "This guitar rocks." And that's the value that's being displayed here for the HTML but let's make this actually be HTML. So instead, let's go up here. And let's use a strong, and we'll make it italics and we'll type this in, and now we've got HTML. Now the binding that Details is using, if we do a quick search down here, it's actually using the binding for text. Now because it's doing that, it probably still won't work for HTML. And as you can see here, where it's just showing the standard text, which is, actually just the HTML tags themselves. But how do we actually do that? So the way we're going to do this is we're going to change the binding here to HTML. So the first bindings needs HTML, the second ones actually, we're going to use text because you want to first show what does it look like when it renders HTML? And the second one here, we're going to render that details again using text. So coming back here and refreshing, we can see that when it's rendered as HTML, it's actually applying the HTML in a browser. When it's rendered as text, you can see what the source actually looks like. This is a quick example of how the text and the HTML bindings work for you.
Bindings: Values: Demo
The value bindings is one of the most used bindings that you're going to find. And here we've got the two, dash, zero, three, B, built-in binding sample. We're going to go through value and another option called value update that you can use to create value binding. So first let's take a look at one of the fields we have. We have model code. We're using an observable here for the name. And then name as well, for the name of the guitar. And then down below, we can see that we've got power value binding down here. We've got an input, the data bind is using value for the model code and then in the right hand column, we're going to display the source for that which would be the Text and the SPAN. So if we view this in the Browser, we can see that we've got the value of 314CE. We change that here and it will update over here for the model code. So let's change that to something like 914CE and as we hit 'Tab' it's actually going to change. So here we go again. We say 814, and as we hit 'Tab' it's going to change in, in fact, all three places here because they're all linked to the same field, which is an observable. So that's the value binding but there's an option on the value binding called value update. So let's see how that works. Let's copy this code first, make it a little bit easier. We've got value here. And let's say we're actually going to use value update. And instead of using the model code, let's use the sale price just to do something different. That's another field we have. And in the right hand column, we'll put in the sale price binding and in the textbox itself, we'll use value, sale price, but let's change this here to use the value update binding as well. It's another option on there. And the default is "change" and you put this in quotes. So the default value is to use, the default operations is to use the "change," which basically means when the input area's value changes that's when it's actually going to make the binding occur. So let's do that here. And in the notes will say we're using "change." And let's do another one because there are other options as well. So for a value update, instead of doing change, this is another option for after key down. This is another common option that people can use, and we will see the difference between using both of these. So now when we run this, I guess we should first make sure that the name of the properties sale price is actually up here and spelled correctly. Yep, here it is. And the sales price is $19.95 out of the gate, flip back over to our browser. And now we've got the different value options for $19.95. There's the sale price. Now as I change $19.95 to let's say, $750 and I hit 'Tab' all the values change on Tab. That's the same behavior as we had up here. So, same change is really unneeded. It's optional because change is the default. But in after key down, every time I press the key, it's going to change the value. So in this case, if I change it to $7,509 soon as I press nine, it's immediately updating. If I delete the whole thing and change that to $5, which would be great, then you can see that the option changes automatically. So those are two of the options that we've got here. We have change and we have after key down. There are two other options that you can use for value update. Let's take a look at those really quick. Now, we can just copy this code again. And we'll put two other options down here for value updates that are just after key down. We can also do key up and we'll just Copy and Paste a couple of places, which is always a recipe for disaster. So let's try it real quick. And then we've got key press, now you probably can guess what these both do as well. We'll keep operating on the sales price, but key up is when the key is released. That's when it's actually going to change the binding value. And then key press is when the key is pressed and while it's held down. So let's see what happens in here. And let's first go up, do a refresh. Now we've got key up, so on key up here, I'm going to hold the seven down and when I let go, you can see all the values change. Let's go back to our normal state and as we're typing it, now on key press, this is while it's held down as well. So I'm going to hold the eight here, and notice I'm holding it down. While it's being held, it's actually changing. So let's change it again to something like one and now on key up again, we'll just show that one more time. We're going to hold the seven and I'll press it once and on up, it's going to happen. That's you see a slight delay there the first time. While I'm holding it nothing is happening until I release. So you can see quickly here with value update, you can change the way that the value behaves. There's the default behavior which is on change, where I can type in like 1995. And on 'Tab' it works, or there's the behavior where I can type as I go, or we have the key up and the key press.
Bindings: Checkbox and Radio Button: Demo
Checkboxes and radio buttons are pretty popular web pages and there's some good bindings built into Knockout to handle those as well. So let's take a look at how we can add some of them. And before we do so, let's go ahead first and add a checkbox down here. We need a value to actually bind to the checkbox. Let's create a value here for property called "Is In Stock," that'll be my property name. And we'll make this an observable using our IntelliSense, and we'll set default as true. And let's bind up this "Is In Stock" property, down below. We'll create a new item down here to put in our example. Here's our checkboxes, instead of saying value, we're going to use checks. This is just going to be a check input. And then instead of using model code, we use that, I think we called it, "is" and look at me I already forgot the name of the property-- "Is In Stock." We'll set the value equal to that. It's not going to be text, it's going to be checks and here we're going to say again "checked." Actually, I do want to put text here because I want to display the value. So what we've done here is we've added a new item in our grid and basically, we're going to say, "All right, here's a checkbox," which we have to tell it here that it's actually going to be a checkbox because we want that HTML element to be a checkbox. And the data bind is going to be checked; the value is going to be true or false, is in stock, which is an observable that we have in our view model. So let's run this and see if we have any problems. One thing I like to do is always check inside the console window and see if there's any errors, there were not. And I'm hitting the 'F12' key to do that. So up here, I still have the value. Here's my checkbox. It's checked to true because that's true. And when I click it off, notice it goes off and then the value is updating the view model because it's an observable to false. And then it's updating the SPAN to show that the value is false here as well. Now let's add a radio button. So switch back to visual studio. And we'll create some properties that we can bind our radio box to, and we'll call this first one "selected color for radio" and so once somebody selects the item from the radio buttons, we're going to store it in this observable field and by default, we're not going to set it to any color. But we also need a property that we can bind the list of colors to. So let's create an array of colors and in that array, let's create some properties like, let's do it with quotes. We'll do "brown." We'll give it a key value of BR. We'll do "name" is equal to brown, and let's just Copy and Paste that. So you have to watch me painfully type through all this. And we'll create three different colors. We'll do a blue and we'll do a black. I'll make the code for this one be, BL. Actually, I guess, we'll have to do BK, something different here. So we've got three different colors that we have all using different key values. You'll notice that the color is not an observable of any type. We're just going to load the data items one time. But we can use Knockout for this. Whereas the selected color for radio is an observable because you want the value to change whenever somebody selects it and then, vice versa. So let's come down here and create a radio button that we can actually bind these values to. The first thing we want to do is actually create input types of radio buttons. So that's pretty easy to do. So we'll come down here and we will highlight the checked items and we'll come in and say, instead of using checked in this case, we're going to use checked and value. And we'll talk about why in just a moment. And these are for radio buttons. Instead of the input box being a type checkbox, in this case, we're going to make one of type radio. You notice IntelliSense is working. Those are my visual studio extensions that we talked about earlier. And here's my data bind attribute and in this case, instead of saying checked is in stock, I'm going to do the checked is selected color for radio. Hopefully that's the name I chose. We'll do a quick search just to make sure. Yep, matched; everything is good. So that's one item in there that I can have. Now, instead of just having one item, because it's no fun just having one, we probably want to stick this at the end too, and it was brown. Instead of having one item, we probably want to create multiple radio items. So here we combine all three of those to the selected color for radio and then we can say, this one is blue and this one is going to be black. And at this point, we're just hard coding in what we want to set up for each of these. And I can set the value for each of these to be something like, I think we had brown was first. We will Copy and Paste again. And then I had blue. And then I had black. So now we have a radio button that we have set up. And we want to display the value over in the far right. So let's display the text value for selected color. And let's run this and hopefully everything works okay. Any errors? No errors in the console, which is good. So now there's nothing by default. When I click on brown, notice BR code is selected, BL for blue and black. Now I'm not taking advantage of the array that I created, so there's another option we can do too. Let's copy all this and it's probably not going to be very useful to hard code your colors in. So instead of hard-coding it in, let's use something called a "foreach." Now the foreach is going to allow us, instead of having three different items for our radio, instead we can do something like surround them with a DIV, if we want to, and then we can say data, dash, bind. Let's go ahead and we want to loop through each of the items that we have in the colors array. So we're going to learn about a new binding here. It's a built-in binder called a foreach. And we'll go deeper into what a foreach does later, but it's pretty obvious what it does here is it lets us iterate through each of the colors that are in our array. So there we can have a list of colors and it's going to spit out each one of these input radio buttons. We no longer need the value to be hard coded to BR, so we're not going to do that. And instead of setting "checked equals selected color for radio" because we're actually inside of the color's array, we want to jump back out, we have to use a special command called "parent" which will allow us to jump one level up into the different data content. Because right now, inside of this loop we're in the data content of colors, we want to be in the data context back of the view model. So we're going out, and saying, "Select a color for radio." Now we don't need hard-code the work for SPAN, for the SPAN either. We can use the data bind actually here, and for this one, we're going to say text is "name." I think that was the property for the color. Let's just make sure that was the property in the colors. Yep, it should say name. So when we do that, we should be able to run this now and we should have a second checkbox down below. Make sure there are no errors; nothing in the console window. When I select brown or blue or black, oops, we've got an error here. We've got all three of those onto the same thing. So we've got to figure out what did we do wrong this particular case. The problem that we have here is that everything is being set turned to on. It's because when I went into the color, I forgot to turn the value back on for the items before it was hard coded to the value equal to BR but now we want to bind that to the key property. So to do that, we need to come back down to our code, where we're iterating and not only have the checked property, and let's pull this down one level so we can see more of it. So we're binding the check, but we also want to bind the value. This is where I said earlier that the value binding can work for all the input types, not just for when you're doing textboxes. This case you simply want to bind the value to the key property for each color. So iterating inside of this foreach, each color has a property. Here's key, and then here we're binding and jumping back out to the selected color for radio. And then we're binding the name of the color. So this should work for us now if we view in browser, we've got it, and we click on brown, blue, and black. And notice the keys are updating in both places. And the reason we have uppercase and lowercase for the names here is here, I typed in the names, down there I didn't hard code them, I used the values that were actually inside the observable itself. And this is how you use the checkboxes and radio buttons with both the value and the checked built-in bindings.
Bindings: Lists: Demo
This example we're going to go through the built-in bindings and help you build dropdown boxes. So first, we're going to create a list of colors again, and in the sample here 2-3D, built-in bindings, we have a list of colors we had in the previous example. And then we're going to create a property called "selected color" which we're going to use very similarly to how we did the radio button. We've got an observable here. And for this one we're going to do an observable. And we're not going to set it to anything by default. We're getting an error because I forgot to put the coma in up there. Now we're going to take that selected color and we're going to build a dropdown box down below. So the first thing we're going to do and we'll just copy this HTML, so I don't have to retype it. We'll create one here and we'll call this "options" because that's what we're going to do. And this particular one here, we're going to do like select with a single selection dropdown, we'll call it. So we'll have a single dropdown list that you're going to select from. So the next thing we need to do is get rid of this input because we're not going to be using an input tag in this particular case. Now we're going to use a select tag. So you can type out the "select tag" here and we know that we need to do some data binding, so put in the data binding as well. And for this, first you have to load the "options." Now to load the options in there's a built-in binding called "options". We're going to use several built-in bindings here. And we're going to use the colors array we already had. When the color has been selected, you want to use the value binding to the observable that we just created and that's called "selected color." Now because the colors are actually going to be using a object array, basically, with colors which have a name and a key value, we're going to need to put the name that we're going to display inside this box. So this is where we say the "options text", that's another built-in binding we can use. It's going to use the name property of the color, and then whatever value is bound to; we want to use this to actually be the key. So basically, here at the last two pieces of the binding, are going to say, well, what are we binding to? So one by one, this is going to the options that load the select box of colors. This is going to be the selected color that we choose, it's an observable. And then here, we're saying the names of the properties on each color that we're going to bind to, to show the value and the text. And we can look at those up in the colors array again. You can see "key" and "name" that we had down there. So if we come back down, we should have our "select box" pretty much set to go. Now we want to set up the SPAN next to it to show what the selected color is, just to kind of show what's going on under the covers. And over here, we'll bind to selected color. Now the selected color, if you get set to whatever the key value is here. So let's run this and see what happens. And we'll check to see if we have any errors. And we did. We've got some errors in here under (inaudible) parts bindings. So it couldn't figure out what some of these bindings were. So let's take a look at what our bindings look like. It looks like over here we've got something mistyped with key. So we'll take a look at that. And over on the far right, yep, we forgot the single quote. So let's go back and try this again. We'll clear out our errors and refresh the page. No errors this time. So you can see that the debugging windows are really helpful. And here we can see the list of colors that have been loaded and the selected items have already been set. And we changed from brown to blue to black. And all that works just perfectly. But what if you want to have a multi-selection dropdown? We'll switch back to Visual Studio and let's create another dropdown list here. And we'll copy the one we had as a starting place. And this one here, we're going to do a multiselect options list. So we'll just say this one here is a "multiple selection dropdown" and we'll slide over so we can see everything we have. Options are still good. We still want to load the same colors but instead of the single value because we want to actually show multiple values we're going to create a new observable called "selected options." We haven't created this yet, so we're going to go ahead and set this guy up and we'll call it "selected colors or dropdown." So this is a binding called "selected options" which is going to store the list of colors that we selected. And then here is the actual observable array that we're going to be using. So hold on to that thought for a minute and let's make sure we got the rest of this set up. We have the "options text" which is "name". We still have the "options value" as "key." One last thing we have to do is tell HTML that we want this to be a multiple select binding, so we can do that here as well, and we're good to go. And then down below, instead of "selected color," this is where we're going to display the value for the "selected colors for dropdown." This is the new observable we're going to create. And we'll put it over here so we can see what that value looks like. And I keep talking about this new observable, so let's go create it. And up top, we're going to create a new observable up here and we're going to call it "selected colors for dropdown." Now, the key with this guy is going to be, he's going to have to be an array. So we can't just create a regular observable because that observable only stored one value. So we want to create an observable that stores multiple values. This is where an observable array will comes into play. In this case, you define it as "ko.observableArray" and we're going to pass it at empty array just by default. And this particular one is going to be an array of observable items. So it's going to track every time an item is added or removed from this array. We'll learn more about these a little bit later. But for now, let's make sure that our code runs and see what happens. Let's make sure there's no errors. No errors in the console this time. So let's see our first list box still works. Now, when I select brown, you can see it over here on the right. If I hold down the control key and select black as well, we can see brown and black and blue. No more brown. And we're all good to go. And all we had to do is set up an observable array to match basically, all the items that are going to be stored for the value. And we go down and see where that was used. The biggest difference here, when you use multi-selection is you use the selected options built-in binding, map it to an observable array. Of course, set the multiple versus when you have a single dropdown list, you use the value. And you can map it directly to an observable.
Bindings: Enable and Disable: Demo
We're going to take a look at the "enable and disable built-in bindings" that you can use with Knockout. And to do this, first we're going to create some properties. We'll create an "Is Read-Only" that we can set up to be a ko.observable and of course, got to put my coma in up here. Make it an observable. And we'll make this be set to false at first, and then we'll create another property. And we'll call this one, oh, I don't know. How about we call this one "allow editing." So first, what we're going to do is say, we're going to have an "Is Read-Only" property to allow to be enabled or disabled, and allow editing as well. And then we're going to scroll down and create a couple of checkboxes that we can use to set up the enable and disable. We'll copy some HTML, come down here, and instead of using value in this particular case, we're going to use the enable, and instead of input type text, we'll make this a type checkbox and the value here will be checked. So when this is checked, we're going to have "allow editing." Spell it right is always good. And then right below it, we're going to have a textbox that we can set up. So basically, we're going to have a checkbox here that's set up to allow editing and then we're going to textbox right below it, where if allow editing is set to true, then we're going to allow editing, and we're going to set the value for this one to be "sale price," which I hope we have a property called "sale price" in here. Up at the top there's our view model and there is "sale price." So quickly, we have a checkbox that we can set up here for enabling, and we want to set the value down here just so we can see what the value turns out to be for "allow editing" and we'll set the text over here. So quickly, we can see how that works. Now we can set up another one for "disable." And disable works the same way enable works, it's pretty self-explanatory. It's just the opposite of enabling. Instead of "allow editing," we'll use the other value that we set up called "Is Read-Only." I'm going to do a little Copy and Paste here. We'll check those off. And we'll set the values up, and we're good to go. So now we've got our enable and disable set up. Let's check it out. The first thing we notice here when it runs, is that they're both set to disable. So that's not the intended effect that I wanted. So we're going to come down and see what we did, and we can see first, instead of allow editing I did the enable. And down below, in the second example, I'm supposed to use disable but I ended up using enable. And let's go back to the browser. We'll run it again. Now we can see that it flipped over to the enabled, so the bottom one should always be enabled unless I click disable. And you can see there, it's read-only as true. So now the top one when I uncheck, you're going to see that I used toggle as well.
Bindings: DOM Element Focus: Demo
Knockout has a built-in binding type that determines or can set, if something "hasfocus" or not. Let's take a look at an example how you can work with this and just to save some time, we'll copy and paste some new properties in here. These are new observables that are all set to false. We're going to set three elements up. A checkbox, a textbox, and a button and determine who "hasfocus" at which time. So let's create those elements down here, and we'll match those up with the properties so we can track who has focus, at any particular given time. First we'll create the line to say "hasfocus" and then we're going to come in, and I think the first one was a checkbox. So we'll set the checkbox, and we really don't care what the value is. So in this particular case, we just want to know who "hasfocus" or not. So we'll use the "hasfocus" binding. We'll set it to checkbox "hasfocus." So there we go with our first checkbox, first element that we want to set to "hasfocus". We're going to create a textbox and a button as well. So here's our text and instead of being checkbox, it's going to be the textbox "hasfocus." This is going to be a button instead of checkbox. And we want an ending tag for the button, so we'll do that. And for the button itself, we're also going to put in here some codes so that we can say, set the focus to checkbox when we click on it. And we'll take a look at how we can set that up, but when we set up the "hasfocus" the Save button "hasfocus." So now we have three elements that are all tracking if they have focus or not. So let's set up a tag down here where we can track in, all right, do we have focus or don't we? And let's show some value for it. So we go a SPAN that we're going to set up. And in that SPAN, let's give it a data bind attribute and in there we'll say, with a new binding type code visible, checkbox "hasfocus" and then we'll put some words in here like, "the checkbox has the focus now." And we're basically just going to track in here which one of these guys are going to be visible based upon who hasfocus at a particular time. And here, we're just going to put in the values and show them on the far right of what is actually happening. And let's view it or run it. Any errors? Yep. We've got an error here; button box "hasfocus" is not defined. There is no such thing as a button box, so I mistyped that. Let's try it again. Let's clear our errors, refresh, no error this time. So now it says, "Nobody has focus. False, false, false." So let's put our cursor up here. When I hit Tab, it now shows the line around the box. This checkbox "hasfocus" and here we can say, "checkbox hasfocus is true." I Tab again, it moves to the textbox, and it moves to the button. Notice that my binding here for visibility is not changing however, so we have a little bug that we have to fix and we'll take a look at that. So we'll switch back over to the Visual Studio. And inside of here, we can see our visibilities and of course, there is no bug other than I mistyped everything. It's called copy and paste errors where I've got the checkbox, textbox, and button now so messages are now different. So when I click on each, you can see that the value changes based on what I am giving focus. But now we want to make a button on the screen, actually, when it's clicked, it's going to set the focus manually. So we're going to use another binding in here called "click on the button." And this built-in binding type is going to call a (inaudible) set focus to our script to the checkbox. And we'll set that guy up. So we're going to come back up to our view model, and we'll scroll down. In this case, you don't actually need an observable what we instead are going to do is we're going to set up a method called "set focus to checkbox" and it's going to equal to a function. In this case, we're going to say, set it to be this checkbox "hasfocus," use our IntelliSense real quick, "hasfocus" and we'll set it to true. Now notice in this case, I'm setting this observable property checkbox "hasfocus" equal to true. I'm not saying equals true like that, instead I'm saying that I want you to actually go ahead and set the property to true as a function. So you have to put the value inside of the function parentheses so it can be set. So it's a common mistake people make, and sometimes they'll do this. And that's not what you want because this is actually equal to the function which is an observable, not to the value. So we want to set this to equal to the value itself. And then with that we now know that the set focus to checkbox is moved down to this click binding up here. And when we run through, we now run it, refresh it, check for any errors, there are none. Now when I click on this button, it just sets the focus to the checkbox automatically for me. So if I Tab off of it to the textbox, and I click on the button "D" checkbox, gets set for me and then you can see over here the value got set to true. And it's not true now when I highlight it because the focus is no longer there. We'll take a closer look at how the click and the visible bindings work in just a moment.
Bindings: Click and Event: Demo
Sometimes it's important to be able to handle events such as a click on an element either a button otherwise. We're going to handle some other event as well. This is where a "click in the event built-in bindings" come into play. And we're going to take a look at that as well as the visible binding. But first let's create some observables so we can track these. And this in the example of 2-03G, built-in bindings click event invisible. First we'll create a observable called "user input" and we'll put a coma up here. User input and we're going to make this an observable. And basically, we're just going to track in whatever the user puts in. We'll default it to nothing and then when the user enters into a textbox, we'll bind this too, we're going to click a button and then display the value. So we're going to create a member on this view monocle display value and it's going to be a function. And that function is going to basically just check first to see if this user input has a value and we'll do length, (inaudible) length, but length greater and zero. In that particular case, we'll do something here real quick, just to make sure the value is there. Say you entered and then we'll do the actual value of user input. Now a couple of things that are really worth pointing out here about user input is notice that I have to use, user input as a function here. That's because user input, when I'm getting the value I want to actually use it as a function because that's what it is. It's an observable, which is a function. So to get the value, I have to put the parenthesis after it. If I leave the parenthesis out, it's actually the function itself. So here I'm saying get this, the view models, user input, check the lengths if it's greater than zero, then we're going to display it to the screen. So with that, we've got our two pieces that we need to do the click. Let's go try that out in the HTML. So we scroll down here to the bottom and let's copy some of this HTML, and we'll create one here for the click. We'll type in "click" up here, now we need a textbox that we can bind the value for, I think we called it "user input", so we'll track that here. And then when somebody puts the value out, we can actually put a button in here. We need to put a button in so when somebody clicks on that button, we know that we can display the values. We need a data dash bind attribute and in there we'll going to set a click built-in binding to display value. And that's got to match the name of the function that we created on the view model. And of course, I need something for the button to say. So that will be "display value" and then here we want to be out the actual value of "user input" just to show what the value is at all times. And now we're going to run this. When I type in the value here of Landon and I click on the button. You see it says, "You've entered Landon." And we see the Landon value ends up over there, it's still bound to it. When I blank it out and I click the button, nothing happens in this case. So that's how I can use the click event. Let's take a look at the event now. So let's go on and add the observables for this particular event trapping that we're going to do. We'll put the event stuff down here, and first we're going to create a variable for, are the details visible or not? So we're going to create in an area where we're going to mouse over a textbox or a SPAN, and then as we mouse over, we're going to show a details area based upon the mouse over and the mouse out events. So we're going to need an observable in order to track the state of this. So are the details available? By default we'll set them to not visible. And we'll need a function that we can use, and we'll call this "show details." And for this function, we're going to go ahead and set up the basic just there. If somebody doesn't mouse over it, we're going to set the "details are visible" to true. And if somebody mouse's off of it, we're going to set those values to false. So here, we're just going to create a second version of that function. And instead of "show details," we can do "hide details." In this case, we set it to false. And now we have "details are visible, show details, and hide details." So now let's come back down, and we'll write HTML for this. First, we're going to create the HTML for the event itself, and then we're going to add the values down here for the "details are visible." So for this we're going to need a couple areas. We're going to need two DIVs, one to show a value that we can hover over, and then when we hover over that value, we're going to need another DIV to actually show. So first, the top DIV is going to have a value. Let's just put in the value here. And we use a binding that we already have, such as the text binding for the model code. And then we're going to bind-up for an event here. Then this is the new event binding that we're showing. We're on mouse over. I want to call these "show details" function. And on mouse out I'm going to bind to the "hide details" function. And then for the second DIV, we're actually going to bind to different values. So we're going to have data bind down here. And we're going to bind visibility. So here we're going to offset the "details are visible" binding up. So if this is set to true, this DIV is going to be shown and if it's set to false it's not going to be shown. And just to add a little flare to this, we'll add a little style. We'll set background color equal to yellow just to make it nice and bright. So we create a DIV down here, and we'll put in a data binding for the text value for model dot name, and we'll stick another one here for good measure for the "sale price." So we should be good to go to actually show everything up, and then in the bottom down here, we also want to show the value for "details are visible" and then we want to show the value to the binding, set up our right column. And when we view this in the browser, now when I click over here, we can see that guy is still works. And you notice as I hover over the event here for the 314CE, it's actually showing the DIV below which we can see is now in yellow. "Details are visible" set to false. But when I hover over it, you can see it's set to true. And this is how you can take advantage of both the click and event built-in bindings to handle events under DOM elements.
Bindings: CSS and Styling: Demo
Sometimes you want to be able to deal with bindings that will bind to styles or to class names for CSS. And we're going to get into that too with Knockout. There is a built-in binding type called CSS and one called "style." So let's take a look at how we can do this quickly. And we'll create a new observable first. We'll do one here called "profit." So if the profit is positive, we'll show the values in green, and if it's negative, we'll show it in red. So we'll come in here and we'll say profit and make this an observable and by default we'll set this up to be negative seven-thousand. And then we have our variable. Now we can come down and we can create some HTML to bottom where we can show up the CSS and the style. We'll do the style first. So first off, we're going to come up here and create a style. And we simply want to say that this particular data binding element is going to have a value. In this case, we'll just make it a textbox and it's going to have a value of "profit" so we can change it and we can actually toggle the different styles. And then, not only do we want that to be a value binding but we also want to use the "style binding" in this case. And style binding can't just bind to a style itself, you want to have some kind of condition associated with it. So in the view model, we've got the value of "profit." We say when profit is less than zero; I want you to then use value red. And then when it's equal to, when it's greater than zero, we can say it's going to be green. Now one problem I've got here so far is in saying all right; I've just said I'm going to set a style based upon a profit that's going to be positive or negative. But what style am I going to set? And that's where I set in here the name of the style that I want to set. So in this case, it's going to be the name of the style. And then, based upon this condition it's going to set to red or to green. And you could put other values in here as well. You can also do "commodore delimited sets." That's why there's the curly braces. You can actually put in other things in here too. So if you wanted to have a border for example, you can just continue onward. But for now, let's just keep the colors for the style there as we have it. And then down below, let's go ahead and actually display the expression. And here we're going to say word profit is less than zero. We want to show the text value for that same expression we had above. So profit is less than zero and then we'll use red or green. So assuming we got all of our syntax correct, we can view this in the browser, and up top we can see that it's red right out of the gate. And then when I change this value to positive value like five-hundred, I Tab out, it turns to green. And we can see the green is showing up over here as well. But let's say we didn't want to use styles because we would prefer to use a class name. And instead, we can rewrite this using a CSS binding. Instead of doing styles, we use CSS. And here we still got the same expression we're going to use, but instead of setting a style, let's set up CSS and assume I have a class quote negative, we use the same condition here. But instead of setting it to red or green in this case, all we want to do is say all right; if we're going to apply the negative class, if profit is less than zero. And then we can also sit in there and tell it well, what if it's positive. So we can then also say, all right; apply this class called "positive" if profit is, we can say, greater than zero or whatever kind of condition we want to do. In this case, we're just going to say wherever profit is less than zero, and then we're going to negate it, just to show you how to do a negation. So I've got that expression and then I'm just saying where it's not that expression. So in this case, I've got the value that I want and it's all set up. And I've got two different classes that could be applied. Now there's nothing saying that these have to be mutually exclusive expressions. In this case, they are. It's either negative or positive. But you can actually apply more than one class if you wanted to with multiple expressions here too. And if you want, you can actually take these expressions and make them functions inside your view model. You might get some of the logic out of here and it's something that I would really recommend, in general. So instead of having profit is less than zero here, I'd probably put a function in my view model that evaluated to that to get this a little bit cleaner, really tidy up. So here we'll go down here and we'll put the same expressions down there, instead of saying all right, in this case it's that. We're going to say, it's negative or it's positive. So let's see what happens when we use this same expression. We'll view it in the browser. Now this time we see it says, "Negatives as red." I'm going to change this value to five-hundred. We can see they both turned to green again since that's positive. If I change it back to, let's see a negative one, two, three, it turns negative. So as you can see, it's pretty easy to use the CSS in style close in bindings and you can also chain them throughout to have multiple classes applied, if you need to.
Bindings: Attributes: Demo
Sometimes you need to bind to something that there may not be a built-in binding for. And in this case, you might want to use the "attr" built-in binding for attributes. A common example of doing this is when you need to bind to show a length for a URL or some kind of an image URL. So let's do an example here where you have a hyperlink that we want to create. And let's say we've got one here called "photo URL." So we've got "photo URL" is our new observable. And we'll come up here. So we create my new observable here and then the URL is going to be pointing to, and I've got this, this is in your solution 314C.png. So this would be an image of the guitar itself. And then we'll also create a URL observable that we can use. So this URL just will be a hyperlink that somebody can set up. And we'll have this point to my website. So basically, we're going to have forty URL which we're going to link to an image and then a URL for a hyperlink. So let's set these up down below in the HTML, pretty easy to do but let's take a quick look. Here we go with the attribute tag. And with the attribute itself, we can do the first one using the A tag. So we'll do two of these. And for the A tag itself; we don't necessarily need to have a textbox. In this case, we simply want to have the anchor. So we've got this in here, and we'll set the data bind syntax up. And we're going to data bind to the attribute using that built-in binding and then access multiple values. So now we're say all right, here's some attributes. This particular element has an "href," we're going to bind that to the URL property. We're also going to bind the title for this hyperlink to model's name. This way we get the title set up as well, and we can see that through the hover event. And then we can also set in the text for a model code. So we've got the hyperlink set up to go. So now the text to the hyperlink will be the model's code and then, the title will be the name and then the URL and click on it is going to be the URL property that we just created. So let's show down here what the URL equals because that's the one we're really focused on. And we'll set the URL up and then when we run this, we should be able to see the hyperlink and when we hover over it, we can see the name, the text is actually the code. And when we click on it, we can actually go off to John Papa.net. Hopefully, I have Internet connection, and I do. So we're good to go there. So let's get back to here now, let's do the same example, but let's do this for using the image attribute. So we can do that down here with image. And images get a little different because obviously, the syntax there is slightly off from the, slightly different from the href. Instead of an href, we've got a photo URL here for the source and it's not arc, it's source. And then we'll set the alt up. We want to set an alt as well. You use a model code for that particular one. And we don't have any text for an image, but I do have a class that's already set up that I can use and it's actually called "photo thumbnail," so I use my IntelliSense that my extensions have put into play for me here. And it's not an A tag. It's actually an image tag, and we don't necessarily need the ending tag over here. So we'll get rid of that. And then down below, let's say we want to track the photo URL and we want to split that out onto the screen too. We can now view it in the browser. And we can see that the image shows up and it's good to go. And we can see that the URL is pointing over here, as well. So as you can see it's very easy to use the attr built- in binding when you want to do something specific like reference an href or source for an image.
Summary
In this module, we talked about all the different kinds of built-in bindings that you can use for displaying text and values, different kind of input values as well, for forms such as checkbox and radio buttons, the submit, the click, the event, enabling, disabling, visibility as well; and then also dealing with focus, styling, and other attributes that you can use for HTML. There's quite a bit you can do right out of the box with Knockout with the built-in bindings. The key to all these built-in bindings is that they allow you to bind your observables in your view model or other properties to the HTML elements in the DOM, so you can have this level of interaction, where you don't have to figure out what the specific attributes are that you want to bind to in a specific browser or DOM that may be different from like IE, to Google's' browsers, to Apple's browsers, and so on and so forth. There's times that you may want to create custom bindings too. We'll talk about that in a future module. But for now, this provides a pretty good foundation for different kinds of bindings you're going to use in everyday development life using Knockout and JavaScript.
JavaScript Patterns: Spaghetti to Ravioli
JavaScript Patterns with Knockout
There are a lot of helpful patterns that you can use to develop and write JavaScript with. Some of those patterns we'll going to take a look at here in this module to help us write some good Knockout code that's easier to maintain and helps us separate our concerns. That actually makes a little bit easier to write the code in some cases too. While there's a lot of JavaScript patterns that you can take advantage of, in this particular module, we're going to take a look at just some on that really help specifically with Knockout and that I deemed pretty easy to use and get out of the gate with. So we're going to start off by talking about spaghetti code in JavaScript and what that means and talk about some examples of where you can find spaghetti code in JavaScript. Then we'll move over to seeing how we can take that spaghetti code and turn it to ravioli code and what does that mean specifically? And I'll walk through several examples at how you can structure your JavaScript specifically with Knockout in mind, applying these patterns to show you how you can might make it a little bit easier to maintain and extend in long term. And that's the key with any pattern is you can understand the pattern and actually apply in a practical sense. It's a lot easier to deal with and maintain and you can really rip the benefits of it. The goal of these module is to help you take those patterns, understand them and actually apply them in a real way to using Knockout.
Spaghetti to Ravioli
Let's start by taking a look at what's spaghetti code and ravioli code means specifically with Knockout in JavaScript. Now spaghetti code is actually that you can go find upon Wikipedia and spaghetti code is defined as basically being code that mixes concerns, has no clear separation or functionality or purpose and it's usually pretty easy to spot spaghetti code as opposed to describe it. And I'm sure all of this seen it at one point and basically a lot of the codes ends up being in a mix, that's hard to maintain, it's hard to figure out what's actually going on, on a lot of cases. So spaghetti code in general is bad because they're mixing concerns, there's no sense of container so what we really want to do is avoid this kind of things with JavaScript because in JavaScript, one of the great things about it is it allows you to write your code in many different ways. But one of the down side to that is the way that 10 different developers write their code in JavaScript might actually be 10 different ways to do it. So while they're all might have their merits, it becomes a little more difficult to maintain when you try pull a code together or maybe read each others code. And also, that code maybe end up with some code that's all just a series of functions for example or you have duplicate function names and different code because you have a lot of global variables. So some examples of spaghetti code with JavaScript are-- let's say you've got series of script tags all over the page. And we've seen this kind of applications where you've got an HTML page, the script code at the top, it's in the middle, it's embedded inside of HTML tags. It might be at the bottom of the code as well. Everything might be a global function for example. I called this the function, function, function syndrome where everything you've got in there is a function basically and sometimes they're not even named or they're not into a namespace. And the function cells are all in the globals. Now they gets back to globals where you night have a global variables or global functions, global objects and these globals might have really good names and it's good to name things well. But if you don't have some kind of a namespace, your global function might end actually colliding with another JavaScript Library's global functioning. Another example of having JavaScript that could be obtained as spaghetti code is using heavy JavaScript inside of HTML attributes. For example not just saying like a functioning that's match view which is of use JavaScripts and you can take a look at that in Wikipedia as well, how that gets defined. But basically, you don't want your JavaScript inside of your HTML 'cause then you're not separating your concerns, you want your behavior-- your JavaScript to be separated from your structure. So one way you can do this is to separate them out and to keep your JavaScript and your script tags or in separate files instead of inside your HTML tags. And sometimes we see inside these HTML tags where you've got not just a name of a function but actual logic laid out with a series of several lines of code inside of HTML. That in general, can be very difficult to maintain. So the goal here is to avoid spaghetti code and get to what we call ravioli code. Spaghetti code while it's loose and it's all over the place and it's hard to maintain, it's-- in a lot of ways just a pile of spaghetti. Ravioli code differs from that because we're basically saying, think of your objects as the simple raviolis which you don't see and know what's inside them. Could be some cheese, could be some meat, could be some spinach but the goal here is to say that whatever is inside of ravioli is kind of encapsulated. Think of those raviolis as your objects. So your objects in these cells will encapsulate and decouple your code, making it easier to maintain and of course extend. And we're handling here is a separation of concerns which is a great principle to follow. Your variables and functions are going to be scoped when you follow ravioli principles. Your functionality be inside a closures, you're probably going to use namespaces instead of the (inaudible) globals. And there's a lot of other advantages to using the ravioli code. So let's take a deeper look at how these could work for you. So the first thing I would recommend doing to get to that ravioli code stays especially JavaScript and Knockout is to create namespaces. I like to have all my names, all my code under a single namespace for my application. I generally call mine "my," M-Y, just to avoid collisions of any of the library that might be out there. You know, as a lot of libraries do this. JQuery uses jQuery or the dollar sign. Knockout uses KO for its own namespace. So it basically can name it, add variable or function, anything it wants underneath its own namespace. These are first and easy step to creating reviolis. And the easiest way to create a namespace is to simply do of our namespace equals and then actually create an object literal. And that basically defines what your namespace would be. There're more elaborate namespace functions that you may take advantage of and if you're interested, definitely check out things like Douglas Crockford's book, JavaScript the book good parts. Another way to this as you can see here, applying these to Knockout, we could have a view model to find of our own namespace. Now I wouldn't name it view model. I'll probably name it late. Let's say it's a costumer, it's a my.customer view model. So here, we've got a costumer view model or costumer vm if you want to abbreviate. So with that, let's take a look at some simple ways you use namespaces and separation of structure behavior and presentation to really help JavaScripts in Knockout.
Spaghetti to Ravioli: Demo
Let's first take a look at how we in get from spaghetti codes and ravioli code by doing a little bit structure in our project. In the project itself, you'll see I've got an HTML folder and also a scripts folder. I'm separating out the structure, my HTML from my behavior, my scripts. And also, I've got a CSS folder incase I have any presentation style too. Here, I'm referring to my namespace JS file for my particular HTML page here. So using Resharper, actually you can see very easily with intel sense, I can type in the name of my file and I can actually go find the JS for me which is kind of handy. It's also a quick tip there, if you're typing is. And let's say, I've typed a namespace (inaudible) and called it my space. It will give me a blue line there, doesn't know what it is. But if I'll come back to beginning of the file, very easily we'll just rename that for me, which is nice and then the line will eventually go away, like that. So some of these tools may very helpful in linking between HTML and JS files too and it works also for CSS and other links. So now that we've linked of the JS files, scan through here quickly and you can see that there is no JavaScript in this particular page. But I do have my finding tags in here for my attributes and I've got some others stuff and options or selection and some other things going on for Knockout. So all that's good to go. Now if you come over our namespace-- namespace JS file and here, couple of things that really paid attention to. One is first, I'm using jQuery's document ready basically at the top. This is the short syntax for it. I like to use this here and as you poke over to jQuery real quick on their page, if you look at the ready handler, we've got-- you can say .readyhandler and there's 2 ways you can write this. This is the more verbals way of doing it which is basically using jQuerydocument.ready and put you handler inside there. So what does it will do for you is all those code will run after the document is ready which is what we want for Knockout 'cause we don't want to be doing any bindings to in element that doesn't exist yet. Second thing I like to do is I shorten and head up to using basely dollar sign handler, which is another good recommended way to go. So over my code, you'll see the two ways to do it the top. I chose the shorter way to do it. The next thing to look at here is we've got the namespace "my" right there. Now as the namespace defines all my functions, this format currency, I've got a product function which is really just being used as a constructor to create model, objects for my products, all my different guitars. I've also got an line item constructor that's going to create instances of line items that I'm going to use. There're all hanging of this "my" namespace. Then I got my view model here which I've abbreviated to "vm" and I'm defining my view model hanging of that namespace as well. So if I go out into the Debugger of this code, I'm going to see there's a "my" global that I've created. And I'm going to create one global and everything of that "my" is where I can access the rest of my variables. So if we take a look at how "my" is defined, again using ReSharper, I'm going to hit control the-- on the "my" key word, it's going to jump over to another file where I've defined that namespace. You could do it in the same file if you wanted to. I liked to define the entire application and it's called "my." And I can name here, it's basically defined as an objet literal. Another way to do this is to say, okay, in case there's a duplicate somewhere else you could say first just create the namespace and use this for the excess if there are excision code, otherwise create an object literal. And there's other namespace functions that you can create too. And also in this file for data, I just happen to put it in here. Generally, I'd created its own file called "namespace." Here's a sample data structure that I'm using. It's also hanging of the global too, so you can see I've got this object called sample data. It's got a property called data and its going to store bunch of "json" that's we're going to use to lower our different guitars. So fully make over here. We seen and we've got our separate files, our namespaces and closures and our globals. And all these code when it runs, or work just fine, we'll refresh over here. We can see if got my list of guitars. I can type in some values, it's all adding up my totals. I can type in another key over here. Let's get 2 of those. I can have the third one to add a guitar. And let's get 11 guitars, why not. We could see down below, there's no errors, down there in the Debug window. I can also remove let's say (inaudible) all those straps. Now, I've got 2 cables and 11 guitars and everything is rocking and rolling. So in this example, you've seen how we can use name spacing, we can separate structure and behavior from presentation using different files and structures inside of our solution. We also see that we can use some of the tooling such as ReSharper plug in that I mentioned in module 1. But this is a really good way to start out by first creating just a global namespace very well of your own for your particular projects that you can make it really easy to use. One final tip, I generally like to make my namespace variable really, really, short because we're going to using all over the place. It's lot easier to type two characters such as MI or MY.
Object Literals and 'this'
There are several ways to create objects that you can use as view models with JavaScript and Knockout. Probably the easiest way to do them and quickest to get engage with is using an object literal. In fact, a lot of the examples that you see with Knockout online, even in a documentation uses object literals. For example, we can see here on the screen, we've got a my.viewmodel object that's defined as an object literal. And we've got both the property name which is defined as an observable in Knockout and a function or member function here called price which is just defined as it's simple function which does an adding between X and Y. So here, we've got this very simple object literal. They're easy to create, they're very common because you don't have to define functions, you don't have a lot of the syntax to add here as quite simple to navigate with them. So that's the biggest fun of it there. It's very easy to go and all the members that you have, they're all available all of time. Some other challenge that you get is when you get a more complex view models beyond the basics. You have problems dealing with the key word this, and we'll demonstrate some of those problems can be as well. So this is really best tutors for simple view models or for data. For example getting "json" data out or you got some kind of just a model structure with several simplest properties. When they get in to dealing with more computed observables and more complex functions in general and you want to expose somethings in your view model as publicly accessible in others, just really for internal use inside the view model as private, there's some better ways to go about it. But let's take a look at how these object literals 'cause in very simple scenarios, these are really, really good to go with.
Object Literals and 'this': Demo
Let's start by examining basic example of using of an object literal with Knockout and MVVM in JavaScript. First we're going to take a look at the examples. We looked there previously in module 1, called MVVM basics object literal, the HTML. Inside of here, we can see a very simple view model, defined as an object literal. These are great example of where a view model makes a lot of sense as an object literal because we can see we just simply have a couple of properties that we want to expose and bind to the Y. And in this simple example here, we've got another property actually a function that works extending off of the view model for my currency. And then we simply apply the view models bindings up through Knockout to the DOM. And the example I'm trying to point it out is that these is an object literal, it's very simple. We don't have anything that's dealing with the keyword this. We don't have to in any these particular member properties or functions 'cause there are no member functions in this case, have to refer back to the view model or any (inaudible) elements. So we don't have any inner closures either. So let's take and look at another example here. This example uses an object literal as well. First at top, we can see we've got our namespace and we're defining product and line and there's a function. Non logic literal because we actually want to create multiple instances of each of these. The function works better in this case, notice some managing to this key word here by using var self equals this. By coming down to the view model. We can see the syntax using an object literal. It's simply open curly brace, no function being defined, just open curly brace. Name of the property value, name of the property value. In this case, we got products which is an observable array. Now managing to this keyword gets a little more complicated when you're dealing with object literals. For example here in add line, that these keyword is going to work because inside this function, this happens to reference-the view model. So I can say, these .lines and it's referring back to the lines I just referred to. However in remove line, this gets a little more confused because in this function, this doesn't represent the view model anymore. It actually represents the line item. So this is slightly different in this case where you've got to deal with this up here and down here, I have to specifically say the name "my view model." Well, just a little inconsistent for my coding likes. And at lower products, we also use to these keyword unless you'd like to write here. But because of the way this is working and no upon intended there until this keyword isn't going to work in this case because it's going to be the line item again. So let's examine this. You've got a low product which is defining a function. So here's one set of closure and then we've got another function which is the jQuery (inaudible) which it's going to iterate through each product and then it's going to define another function for the for the call back for each individual product or P is going to represent the product I'm looking through. So on several closures in and if I used this key word and I examined this, it's not going to be equal the view the model. It's going to be equal to something else. So I have to say "my view model products" to be a little at items to view my models products observable array up here. Not too difficult but it gets a little more complicated there. Now, skipping over this guide here, the reason he skip is because we actually have to define this computer observable outside of the view model. So we're extending the view the model to create a grand total function, a member as a computer. Now this computer is going to accept the owner as a view model. Why is that key because this my view model as we learned earlier is going to be represented in to this keyword down here. So in this case again, the owner is going to be the view model. This is going to represent that view model and therefore I can use myviewmodel.lines here or this .lines very simply. But I had to that outside of the view models object literal definition because it didn't work exactly, right? When I did it up inside of the view model itself. So if we un-comment this code out and let's go ahead and comment this code down, we're going to see a couple of things happen. First, I've got some test variables in here, just to check out what is the value of this, what is the value of view model, it's not going to be the right thing in either case. This isn't going to work because it's not going to be the view model. It's going to be the DOM window. And my .vm doesn't actually exist yet because inside the computer, 'cause it's still trying to figure out what the computer is at the time the view model has been created. Some kind of stuck, I can't really refer back to I need. I could do some kind of self referencing and some other stuff in here but it gets a little more complicated. So these codes now actually going to work right which means when I'm iterating to the lines, I don't really know what this is. As I mentioned, it's going to be DOM window. It's not what I want. I want a view model slides so let's do and have run these codes through the Debugger. We'll flip up to the HTML or run this in the browser and here, we can see there's no data, probably an error. And we do-- if we look in the cancel window, it says that the object DOM window has no method lines. Flip back to our code, we can see that it's actually referring to these reference of lines. With these keyword, let's use the Debugging tools. We'll pop on the scripts, this is inside of chrome or choose the object literal JS, we'll scroll down until we see our grand total function and down here, we've got a grand total function but a break point there, after we actually checked out with XYNR, in this time let's just refresh page. We stop there and if however X which is equal to this. You see it's the DOM window so I certainly don't want this keyword because of this keyword, it's actually going to not have the lines in it. Well, my.vm should work, right? Well, that's actually not defined yet. So that doesn't work for me either. So when I get down to this top lines, it actually has no idea what this top line is. If you go to the cancel window, we type in my .vm, we can further see it's undefined. We can take my (inaudible), what's going on my namespace? And this is another example of why namespaces are good. We can everything have defined, here's my line item and my product functions which are going to be my constructors are creating new instances of those. They're defined. My (inaudible) currency function is good to go and my sample data which is defined in the data .js is working great too. And of course, the prototype. But I don't have my .vm yet so what I need to do and first is to un-check that. Let the page run through. I need to come back here and we're going to get rid of all this code. Let's comment that back out. We'll come back down to my other function and as we run this page and it will run the page. This time, it should work just fine and we see it works great. And let's check out the Debugger. We go on to scripts and we go back down to the object literal page and let's put a break from right here on each and see why this lines works for us. And again, we'll refresh. We refresh down here. We can see in this case, this has add line-- lines, load product, all these fun stuff in here. This is actually my view model, my .vm. So and that's because we're passing in my VM which you can see is right there. So now I can go and say, "what's my VM?" It's my object before I head on the define and remember. So here's everybody is good to go. I can type in "my" and you can see under "my," I've got my VM. So all these works really nice in this particular case and the big difference was I defined the grand total computer outside of the object literal. So there's easy ways to resolve how to deal with this key word. The point here is that when you use object literals it's a little bit work sometimes to handle this keyword. It's not hard to do. There's just little bit more work but if you're using simple view models with out a lot of other functions, sometimes the object literals are easiest way to get going.
The Module Pattern for ViewModels
( Pause ) ( Pause ) Perhaps one of the most, if not the most popular JavaScript pattern is called the module pattern. And a model is basically just the function that you define to create your object. Now these three key areas we're going to focus on using the module pattern for creating view modules for Knockout. The first is anonymous closures which basically allows us to create a function that's encapsulated inside of itself so other variables inside of it are not exposed outside. We'll also take a look at immediate function indication and how that can help us by creating a function expression as opposed to the function definition. And also at private and public member scope that we can use. First, anonymous closure is basically taking a function and wrapping inside a parenthesis to become an expression. In here, we've got a function which we can define whatever we want inside it like our view model. All of its public and private members inside to there and all those are scoped inside of that closure. It just helps us contain everything we wanted to and keep that ravioli effect that we've been talking about. The second piece is immediate function indication. So when you create a module or a function in this case that represents the object module, it's going to be immediately available if you use the immediate function invocation. It basically means, (inaudible) of the end of it. So basically, everything inside of the function is going to be instantiated as soon as it hits that and then it's going to be step two, this instance inside of my doc view model. So we're basically saying, take my doc view model, with other namespace and define that as everything inside this function and run it right away. The third piece we're looking at is using this same concept but now adding in the concept of the private and public members. So the key thing that the model allows you to do is allow you define different members that you have. And in this case, we've got a val, which is a private value, just with the bad name of course, called private val and it's going to be privately accessible inside of the function not outside. And then the return object is going to return in object literal. So when you do access my view model, because the "my.model." and you could say public val or .add. Both of these guides here are going to be publicly accessible outside of the view model. So that's really important because now we have a concept of the private and publicly accessible members. The one down side of this is this once again. So what is this mean? Here we've got public val, which if I want to reference it inside of this add function here, I got to say this (inaudible) public val. So all the public variables are going to be accessible using this key word. And then over here, we don't have to say this because that's going to be privately accessible inside of the object. So this is going to represent the view model and we can actually represent the view model here because it's inside the return object. But the key to remember about using the view model with the module pattern is that you're able to segregate out your private and publicly scope members. Now one kind I have to mention as well is you don't need to have a return object to use the module pattern. You can actually define everything through the var key words on top. So you could say var is my private val or public val and I add every-- any another function or method or member you have. All of those will then be accessible externally about creating a return object. You're only opening up and exposing some of those properties which is a nice handy thing to do too. So there's a lot of advantages to using the module pattern because it allows you to basically more-- separate your code into cleaner segments of what's public and what's private. And some of the benefits here of module as your code, can create your variables and functions taken out of that global namespace. Once again, you're using the closures to do that and you can expose only a public members and hide a lot of your private code. One of the challenges that you have to is access your public and private members differently as we saw on previous example. Another challenge that you have is sometimes when you're looking at the code and we'll flip back quickly, when you're looking at the code, these methods here like add, they can have a lot of logic. This is a very simple function which actually doesn't do all that but you can have a lot of logic here. And if you have a lot of those, it gets a lot harder to maintain and look at. And there's some other techniques you're going to do to clean that up. But let's take to look at how we actually implement the module pattern using Knockout. ( Pause )
The Module Pattern for ViewModels: Demo
Let's take a closer look at how we can use the module pattern to define a view model. On the left hand side of the screen, we see the module pattern example. We're defining my VM equal to a function. And then on the left-- on the right hand side, we're defining my .vm is equal to an object literal which is the examples on the previous section. So here's the object literal on the right and on the left, we're doing the same code but we're using a module pattern. So the first thing you notice is instead of just saying, it's going to brace to create an object literal. Syntax is here's my function and then you open up this (inaudible) brace here and then at the very end of it, we scroll down, we see that we're actually using the immediate indication at the end of the end of the module pattern. Now we could wrap this in a automatic enclosure as well which could easily be done. We could wrap him up and we can put him in a place just like that and still good to go. And that's actually more of the preferred style that people like to use with the module pattern. Next thing we notice is we can define variable's members inside of your-- as private by using the var key word and then anything exposed to return is going to be public. So here's a private variable products. And on the return statement, we actually expose products with the same name. And I could rename it in this case to like products two or something else. That's fine as long as the right hand side refers back to the inner variable that we're using. So we can see so far just as in tactical change. Now we run this example, we can come over to our solution and we can click on module pattern HTML. We'll first make sure that it works. It's up here, we've got our example running. You can select two items at the another guitar and we can remove items. No errors in the cancel window, we're good to go. So earning works here, when we run this guide, we noticed there's a couple of things that we can do to refer the variables that are public or so private. So anything defined in the return statement can referred to as my .vm.products or add line or lines. All these stuff in returns can be bindable using Knockout. And anything it's up here will not be variable. The only reason this one is bindable is because we actually exposed it down here. But one of the key things for using the model pattern is let's say we had other variables here like private val equals three, that's going to be private. Notice it's gray Resharper is showing me here are the tool values. It's showing me that it's gray because it's not being used. And public val is public. So if I try to use that which I don't recommend doing alert in here but let's say I just try to do an alert real quick. I can say this public val plus private val, I can return back to value. Notice I had to say this for the public val but not for the private. The private values can be referred to inside of the return object just by saying name the private value because it's using that scope. The public value which uses the word key word of this because it's referring to the object that you're in so this is actually in a closure here again. We're retuning in object literal, starting here and going down the page and then inside that object literal, this key word is going refer back to that object. So let's say this public val, 'cause that's what you're referring to, plus the private val and then or course this is no more to grade out because the private val is actually being used here from the alert. So if I run this guide and I closed him, so let's go run him again from HTML. We'll view the browser and now click on (inaudible) and click remove. We're good. I click on add, notice it says, "ten." So let's click back to our code. This value is seven, the private value is three so we add the two together, that should be ten. Let's get where the object literal a little bit. We'll just scratch it over. So when I add this two together equals ten. But if I had taken this and try to do public val and this top private val like that, let's see what happens in this case. So let's refresh the page and let's go and to add more something. We'll add products and now we're getting an error some sort. I can back as this is public val is not define. We click over debugging and has no idea what this public val is. So it's been a break point there and try again. Now just click add over public val. Let's see what value comes up and it's not defined in this case. If I click over private val, it's also undefined because this is exposing the return object and there is no private val in this return object. So both of these would actually fail in this particular case and I get nothing, which is not what I wanted. So what I really need is to do this for public and not for the private. So that's one thing you have to keep in mind when you're doing the module pattern. The other thing that I'd like to keep mind here is that, anytime you have a function like remove line or load products or add line, this again can be pretty big in some cases. And they can actually get quiet complicated. So when you do this, you're actually loading everything that's public down the return statement which is kind of cool because then everything in the return, you can easily see is exposed publicly. But the down side is, then you're showing a lot of a logic inside that return. So it's not showing your true interface of what's exposed without having a model through over the different look count lines of code. Another thing about the module pattern is that it doesn't solve the problem we had in the previous model with to this key word. And quickly to recap that, this grand total computed function here, I can't pass on the owner because the view model is not existing yet. And I can't actually refer to this the proper way because the object doesn't exist. So I'll actually want to refer to this inside of you and figure out what is going to be. We'll go a head and comment out the redefinition of this down below. Now when I come up here and we run this inside the browser, we'll again go over our solution explorer. We run through this using the module pattern. Notice that it immediately got an error. Let's check out what the error is. It says, "The DOM window has no method lines and that's because this key word here is actually equal to the DOM window. It's not equal to the view model. You know I passed in my .vm so that's not what we want to do there. So let's try this in different way. What if we passed in to this key word here, which will then represent this inside of the computer function, 'cause that's the owner variable we're passing. And let's refresh the page and let's get little break point. We'll run through and we're still getting an error. Just to make sure we're doing the right thing, let's refresh the page again. Same error, same line in this case and how we can refresh, let's try it again. Now we break point on here. This is the DOM window. Even though I pass in this here which technically, we're taught that this is going to be the value with the return object or when you're inside the computed functions, things will get little a different. So doesn't actually work that way for way. So if I go over to the "cancel" to check out my, we can see what's in the my space, we can see that vm doesn't even show up. So while the module pattern helps you with somethings, it doesn't help you with this key word inside the computers, inside of the return statement. In this case, I still want to actually extend my view model using the grand total. So in recap, the model function is really nice for exposing certain things as private and publics. Here's our private variables. Here's our public variables that we're going to expose, functions and or properties and they can be observable or observable arrays or computed if you need to. And then you can also deal with the-- this key word (inaudible) differently again. In some cases, it helps with somethings with the-- this keyword but with others, it doesn't. So that this key word again, we referred to any as public but not private. When dealing with computed, it gets a little (inaudible) again. So in the next section, we'll take a look at how we can use the Revealing Module Pattern to even make it as step better and help solves somebody's problem they're having. And this just brings us one step closer as we go through these patterns to having much more maintainable Knockout application.
The Revealing Module Pattern for ViewModels
The module pattern is very popular in JavaScript but there's one other pattern that builds upon. It called the revealing module pattern which adds a few extra things to really make it even better. So with the revealing module pattern, it can only benefits the module pattern plus helps clarify a little bit what-- this is doing for you to this key word. It clears up what's public versus private and helps to reveal private functions with different name. Here, we can see in the example that we've got my view module and at bottom, we're returning out an object literal which is going to contain some val and add. So the only public members that are accessible over my .viewmodel are some val and add that we're going to expose. And then private val in the add function open the private variables are actually just going to be internal variables for this enclosure. So some val specifically refers to private val. What that's doing there as there's some val property is going to be a public property or public method that's exposing and pointing to an internal property or method called private val. So greatly, you can rename methods as well. And in-- as the case of the add function, we can see the add functions using the same name which is just the choice that you have but it's using the name here. This point to an internal function. Now the key to this in using Revealing Module Pattern is that, usually the return statements are very, very short because they're exposing, here is the name of the property or member that I'm going to be exposing. Here's the points to internally instead of having a lot of logic here on the right hand side. Whereas in the in module pattern, you can have a lot of logic under the right hand side. So it's just really a style of coding. Another thing that the Revealing Modern Pattern helps you do is you can help avoid having to refer to the public properties as this dot and then dealing with the private properties that having to do to this. So in the previous example with the module, inside of our code here, we have to refer to a public property saying, "This .mypublicproperty plus private property." So the private properties don't require that to this prefix and the public properties would using the module pattern. Is the revealing module pattern, you don't have to worry that it helps kind of avoid a lot of that since you're moving things up or your logic into your variables, your various statements up here, for your variables, for your properties, for your methods and functions that you have. And then you really chose the return statement to return out and exposure your interface. So with that, let's take a look at how we can apply the Revealing Module Pattern to a Knockout view model and show what advantages it might have.
The Revealing Module Pattern for ViewModels: Demo
Let's take a closer look how the Revealing Module Pattern can help us with Knockout. In this example here, we can see that we got the same code running to add products, remove products. We can have products to the list, we can change their quantities. We can have a second product down here. Everything works perfectly. If we look, there's no errors. This is all using the Revealing Module Pattern. That's an example 4-04 Revealing Module Pattern. We go to look at the code, we can look at side by side to the module pattern. And the reason I'm showing you this here is to show the slight differences between them. On the left here, we get the Revealing Module Pattern which you can see is got a var up here and then it's got a bunch of products and lines and add lines and other kinds of functions and variables defined below it. All these are private. Whereas, on the right hand side of the module pattern defines only one or two things private and then all the logic in the publicly exposed members are all defined in the return statement. So it's really, there's this semantical differences that that things are lined up that way. Now at the surface, that's all it looks like. And then as we scroll down, you can see in the Revealing Module Pattern, it's very clear what's being returned. This is the public property or method, the member that's going to be exposed of my .vm and here's what's it's going to point to-the internal name. So the method that a property is going to refer to the method (inaudible) properly internally and so and so forth. And all these just happened at point to the same ones. Whereas in the module pattern, the return statement does the same thing other than that on the right hand side, it's not pointing to an internal property or method that's using. It's actually defining the logic right here. Now in the module pattern, we had a few issues with this key word. So we're going to take a look at how that actually helps gets the results slightly with the Revealing Module Pattern. So in addition to being just a little bit clear on what's being returned and exposed, the Revealing Module Pattern helps us clear up this. So in many cases like right here in the module pattern, we were defining my.vm.lines to point to the lines observable arrays. We could push new items into it. And this keyword wasn't going to work because of the closure and I'm clearing around this so we could just say my.vm. But I want it to be nice and I have to deal with my.vm here, in other places we we're already using these. Other places, we didn't have to use either one of them, that was the module pattern. In Revealing Module Pattern, we can just say lines.push because all of these members are being defined privately in the private scope. So therefore, they can access each other, so lines in this case is all we need to say. I could say my.vm.lines but why not to say lines, very consistent. Same thing with the remove line. Here again I can just say lines that remove and that will work perfectly for me and then down inside the load products which has multiple closures because we get to function here, the jQuery each. And then another inside of this guide, we previously we're having to say my.vm.products to get to the products. Now I can just say products and every thing's good to go. So if when run all of these just to prove it here, we can select items, we can change we can remove them, we can remove if I get rid of the break points, we can remove multiple guides at a time and then add product and well go back to the web window and there's nothing showing up, the cancel is being in there. So we know that's working just well. And if we want to click into the scripts, we can actually put breakpoints down here and let's put one here at lines remove, so I can remove a line. We can click over the lines object and we can see it's actually an object. If we want to, we can just say, all right, what's in lines? There are 2 line items and we can see there's 2 on the screen. So when we go back to the script, we let that guide run, we just removed one, we'll add a lot or we'll specify a line item. And now let's add a line item. We'll put a breakpoint here on the add function just to show you what I'm doing there. When I click in "add product," lines down here is also an object. We should have one object in there already so we're good to go. And now, we add through and we say another, we should have 2 objects this time which you can see right there, we can type into it, looking at the properties, using the cancel window. But there is another example besides just clarifying this. There's another example that Revealing Module Pattern really helps with. And as to this keyword, gets a little bit easier with the grand totals. If you remember previously in the module patten example, we'll go take a look briefly. In a module pattern example, we have the grand total defined at the bottom of the screen, extending the view module object because there's some issues we have in passing in the owner of when that these keywords available and what it meant and what the my.vm was being created as. With the Revealing Module Pattern, I don't have to create that as an extension. I can define grand total internally as a private member and all the variables are working fine. Part of it is because lines can be referred to directly in this case, which lines us the observable array. And then, I can just expose grand total publicly on a return value. So when I come up here and I click on different items and let's get rid of the cancel or move on here, we can see that it's actually calculated in the grand total. So if I change this to a really big number of guitars, we can see it's all getting calculated on the fly. So the keys here with the Revealing Module Pattern is first, it helps you clarify how the module pattern is returning its members so these are publicly accessible members on that view model. And it helps clear up a lot of those things that this key word can get cumbersome with. So you don't have to use a lot of that notation to get to your variables. In this case, the lines are all being referred to just by saying, "lines" which makes it a lot easier to deal with. And let's take a look at how this is just publicly exposed inside the browser so when I come through here and we click on the script window, lets go down and click on a break point for the-- let's go to remove line items. And when we click on remove line item, let's take a look at what is my equal tool. So here's the my object, that's my global namespace. You can see the view models there, my sample data and then my constructor, some other objects. I can also open up the view model object. So right here you can see in my view model, these are the properties that are being publicly exposed. And these are the same matching properties that we would see right here, 1, 2, 3, 4, 5, 6, 7. Those seven properties. 1, 2, 3, 4, 5, 6, 7 plus the prototype for the object. So the same seven members are being exposed here as we show on Revealing Module Pattern earlier. So hopefully, you're seeing the Revealing Module Pattern as a nice way that you can really clean up your JavaScript with Knockout it really take advantage of the data binding features that it has by producing a very nice and maintainable application. And because of all these features that the Revealing Module Pattern helps you with, I really recommend using this when you get into more complicated view modules for using Knockout with JavaScript.
Summary and Tips
In this module, we take a closer look at how we can apply popular JavaScript pattern such as the Revealing Module Pattern to apply to Knockout and MVVM style as well. So it really helps us take our view models and bring them up a notch so we don't have to worry about things like globals and to that closures. We know what are variables are going to mean. We also eliminated some of the issues we can have with .notation, where we have to figure out what does the this keyword mean. How do we pass in the owner of an object and how do we refer back the object themselves. The overall goal of going through this patterns and using them is to make your code a little more extensible and maintainable and obviously, easier to read. So we review the couple different patterns here. One is just using simple object literals which is still very good for doing standard view models which are mostly basic properties that you're going to be handling. But we'll also look at the module pattern and Revealing Module Pattern which are much more suited for larger view models where you're got more inner activity with more functions using computed, using observable arrays and combining all this together with (inaudible) of other behavior that you can use. But one of the most basic patterns we also looked at is separation of concerns, where we have to separate presentations, structure and behavior. Presentation being your CSS, structure being your HTML and behavior being your JavaScript. Very easy and separate these things out and make it to all your code, isn't combined in one place or in a mix through out the page. So just by separating into separate files in your solution, that helps one way to deal with them. But also, even inside these files, making sure that you structured your code properly for your JavaScript so this model should show you how to get from spaghetti to ravioli and hopefully made you hungry for more. So stick around for the next module.
Templates, Control of Flow, and Containerless Bindings
Templates, Control of Flow, and Containerless Bindings
As you start developing applications in Knockout, you're going to find yourself wanting more than just simple built-in bindings. And there's couple other features that are really, really advantageous. And some of my favorite of these are handling templates, control of flow, and containerless bindings. In this module, we'll show you how to use all of those. First, we're going to start out with name templates, showing you how you can create templates that could be easily reused throughout the application just by calling their name. The more we get into control of flow and show how we can use things like foreach statements and if statements right inside of our bindings. We'll talk about how binding context work for you as well so you can dive into an object hierarchy such as your inside of a template and then the context for the data might be, let's say a person, and you want to go back up to the root context that might be one of two levels up. You can use combining context to change the context from person up one or two or other types of levels. This is similar to using the RelativeSource ancestor binding that's in XML technologies. Inline templates are also very handy because you can create a template that is right inline with your HTML structure using this control flow statements which is very handy as well. And for those times when you want to be able to change the templates you might rendering from one template to other dynamically, we're going to talk about dynamically choosing a template and show you how to do that through Knockout. And templates also have binding helpers which allow you to pass data in or handle things like "After I rendered, what do I do?" or "Before I remove an item, what do I do?" So I'll show you how you can use some of those binding helpers. And then one of my favorite features is containerless bindings which is new with Knockout 2.0.0, it allows you to create-- containerless bindings means you don't have to actually have div tags and spans just to create some kind of a binding structure, you can actually do it with containerless bindings which are basically HTML comments, and these really come in handy in a lot of situations. So by then end of this module, you should have a great understanding about templates and control flow and all the different kind of binding context can help you build really robust Knockout applications. ( Pause )
Named Templates in Script Tags
Knockout has named templates which allow you to create a template, give it an ID, and then point to it and use it multiple different places. This allows you to reuse the color pretty easily. This assigns responsibility for specific rendering to a template that you can use in one or multiple places. Sometimes it's nice to just have an external template that you want to be able to point to as well. Knockout supports many different types of templating engines such as jQuery templates, Underscore, and has some future support coming up from other engines too. But Knockout also is not dependent on any of these engines to do templating. It has native built-in templating engine that allows you to create temples and reuse them as often as you like. So you don't have to take a dependency on another engine, you could just to use Knockout. The way we start of with name templates inside a script tags is to create a script tag and then give it an ID, such as "person temple," and then here we can see that we've got a binding for first name, last name, and then a click binding to select something with select person. So we'd have some kind of a view model bound to this and then the div up top is defining the templates name to be "person temple." So when this div gets rendered, it's going to look and use the template binding, it sees its name as person temple, and is going to find that script tag and then use that to render a data binding. And the context of that becomes the context in this script tag, and this template becomes whatever the context was up hear in the div tag. So let's take a look at the demo on how this works.
Named Templates in Script Tags: Demo
( Pause ) So here we have an example called 501 name templates where we're going to create a template out of some code that already exist in this sample. And if you run this sample as it is in the before code, and you view in the browser, it's going to produce a list of a shopping cart and, you can add items, you can select the item, they show up here, and you can have more items as you go and shop to your hearts content. What we want to do is we want to take totals down here and put this into a template and then reuse it. So the way this is going to work is we're going to go over to the code and take a look at the structure. Now here in the HTML, we have all our structure that's laid out and then all of the script code for this one, this view models is going to exist any matching named to file. Now, the matching named file, or here uses the revealing module function which reveal a module in module pattern which we learned about in the last section, and here we can see that we've got models for the guitars, products, other objects that are being created, line items for the shopping cart, and then of course the view model itself. So all this is laid out for us to use and we've got a grand total function which is computing all the line items totalling and pulling up the extended prices. So inside the HTML, we have section at the bottom for our footer which contains our line items. Now, let's open this up a little. So down here, we've got this div and its got this text in the here about items in your shopping cart. Now to create a template out of this, it's very simple to do. First, let's just take that code, we'll cut it out of their and let's go create a script tag. So we're going to create a script, type equals, and let's just type in HTML. And then, here's our script code and we're going to copy that code back in there and voila! We have a script tag. Now the next thing we have to do is give this an ID's. So we can call it something like "totals temple" and then we can come up to the template where we want to put it and now we can use the data binding syntax for Knockout to say data bind this, data bind the template. And this actually accepts the parameter of object type where the name is going to be equal to-- they could call it totals temple. So that's should it right there. Now, we had this div up which looks likes it has nothing in it but it's going to refer back down to the script tag to insert here. And in the context of the script tag of this totals template is going to become whatever the context was up here, which in this case is actually part of the view model. So, now we run this code, you can view it back in the browser, it rerenders. And we see now, we've got our items and we see 24 dollars. And every time we add something else in to here, we can see the prices will change. So this demonstrates how you can take your code and you can move it from outside of HTML structures that might be in and move it into a script tag and then refer to it as a template. So you're templatizing your code in this case. It's fairly easy to do and there's couple other ways to do it as well. So let's take a look at those in the next example.
Named Templates without Script Tags: Demo
Well, Knockout allows you to create templates inside of script tags. You can create them on other HTML elements as well. So you can put it like a div, for example. So let's take a look at the example here which is under module 5, name templates without script tags. And this one here we can see we start off, again, we've got our products and we're adding them up and then down here, we've got our footer. And currently in this sample, this element is not inside of a template, it's just inside of a div. So what we could do, is we could templatize this by pulling it out of the div again, and here we could say, let's data bind. I've copied that other code in the space so we can say data bind to a template named-- and that template name, let's call it "totals template." And let's go create the totals template. Now, instead of a script tag, let's go down to the bottom of the page just to show where we can put these anywhere 'cause it won't matter. And let's create that template there and let's name this template. And now notice I called a div and not a script tag. Here we're going to name this template, "totals template" so that's going to match the name, if you look for that again, it should match the same name, we found up here in template, although, we must build template correct. Tempalta is not the foreign language version of template. It's supposed to be spell template. And then coming down here, we've got our div which is now matching that. Now, that itself will be fine, however, one problem with this is because in a div, it's going to be displayed all the time. So, what you could do is you could set the style here equal to display none. And now, this div becomes a hidden div, doesn't consume any space and then when Knockout sees these that it's bound to this template, it's going to notice that it's a div, it's going to notice that it displays at the none, it's going to change that to become visible for us. So we if run that sample again, now we have a template version of the sample, we'll click back into it and notice we have our totals right there, total is zero. And as we change this, everything is good to go. So this is just another way to create templates. You can do them inside of a script tag or inside of another element, doesn't have be a div. It could be another kind of element like a ul for example or a span. As long as you get an ID, 'cause you have to have a name to call it by, and then, you want to give it a style and display none in this case. You don't have to get the script tag in display none style because it's never displayed unless you tell it to be. So, this is one of the way to you use a name template.
Control of Flow and Binding Contexts
Some of Knockouts most valuable bindings are actually the control flow bindings. In this section, we take a look at those as well as how you can change the binding context. So the control flow bindings are if, ifnot, foreach, and with. The if and ifnot bindings allow you to evaluate a condition to see if it's truthy or falsely and then to execute something based upon that. This can really in handy when you want to execute or only show certain areas of HTML elements and bindings only if a certain conditions exist or if not. So basically if not, it's the opposite of the if. And then using the templates, you use the foreach quite a bit actually and we're going to show that in just a moment where you can actually iterate over items using the foreach. So you might be bound to a data context of your view model, but you have an observable array inside that are called products or line items. And you want to loop through those, you can use the foreach on those products for line items and then the context will change to each individual item in that observable array. Then the with is basically a shortcut to execute with the object. The with also happens to evaluate to a truthy condition. So it's kind of like a combo of using the if and a with together. Let's take a look at each of these quickly. So first, with the control flow for template, we saw that we wanted to loop through certain items in the template earlier. So we want to take this template and have it iterate through each line item in there. So we're bound to some kind of a view model and it's got to lines observable array. And then that line's observable array is going to be passed to the foreach and then it's going to iterate through one by one. So this template down here is actually going to execute for every single line in the observable array. Another control of flow is the if and here we can see in if truthy condition. So we're saying if the lines dot length, if this observable array's length is greater than zero, I want to show the total value and then the grand total that I'm going to be bound too. If there is no item, there are no items in that lines array, observable array, then I'm not going to show any of these two spans at all. So it just helps create a little bit of structure and flow inside your code that you can do here. I could have actually said if lines dot length and gotten rid of the greater than zero as well because the if lines dot length would evaluate to a number, zero or higher to determine how many there were, and that would be truthy condition if it was one or more. And I could just say, if lines, you know, I was just checking to see the existence of the observable array was there as well. So a couple options you have. The with is a special one that should take advantage of and it's best to show the before and after. So for example, here we've got text and were bind to the model dot brand property. So this could get really complicated in the things like the canonical address example, where you've got address to the city, street, and zip and all the other information that could go in there for the local. So you could be repeating this object over and over again. In this case, we're repeating model multiple times. Well with the with, you can actually bind up in the top div and the container would say, "Okay, everything inside of this div is going to be bound to model. So therefore, the data bindings inside can just say, "All right, brand and name." So we've gone from this to that which with two lines of code, is not a big deal, but if you have something that's got a lot of sub elements and you want to keep diving into the code, this can become really, really helpful. Now when you're dealing with binding context, you see that we change it slightly with the with, but sometimes inside of templates, you have an object hierarchy that you need to navigate. And there's four special binding contexts, operators, that you can use. Dollar sign data is going to represent the data that you're currently is the context. And this is helpful if you're looping through a strings, for example, and you want to actually show the string inside there, you can just say, dollar sign data, 'cause you may not have a property to show. The parent or parents in root allow you to go up to the chain in the object hierarchy. So you might use parent if you want to go up to chain to fine an item above you or parents will find multiple parents. You can also daisy-change these where you've got parent dot parent, you're going to go two levels up. And root takes you right to the root to the data context. So quick example here is I might be inside of a data template and I want to bind my click event for a bottom to the add item property, one level up the object hierarchy. So maybe I'm inside the view model and I'm iterating through its line items. And when I'm entering through the line items, the line items in cells don't have an add item method. But the main view model does. I can say parent dot add item. Or in this case, if there was two levels then I could say, dollar sign parent dot parent add item. But it helps you show how simple it can be to use the binding context to go up and down the chain. These are really, really helpful inside of templates. So now, let's apply these to some demos for the control of flow and binding context.
Control of Flow and Binding Contexts: Demo
Let's take a look at how the control of flow and binding context can help us create better templates in a lot of ways. So here in example 5-3 control a flow, in this solution, we've got a half written template already. Now we want to do is in this body here, we want to create a list of line items that we can add to a shopping cart. So up here, we've a got our product and price and our quantity in our header. The product price, quantity, extended price, like we saw on the previous example. Now in the body, we've got all these TR tags that we want to spit out for every line item that we add. So to do this, we want to create a template first. So we want to bind up to this template and we'll first grab all those TR tags and let's come down and let's create a script tag, just like the one we had for the totals, and you're going to spell script right first, it's one of the keys. And then we got to script tag, it's not happy because it doesn't know what that is yet. We'll type, type and it's not C Sharp, we'll make it HTML and I need to give this an ID. Let's call these products templates. There we go and I don't like all that being unindented, so let's highlight it and let's go ahead and pull it back a little bit, that's good. So now we have our template over here. Now, we need a way to refer to it. We can copy the syntax that we used earlier to create a new template here. We're going to data bind to this template, so template not tempalta, template. Here we go. And then we're going to say that this is going to be equal to these objects, we can pass in several parameters, the name of the template is "products temple" and I've put that in quotes because it's the name of the template, not actually an observable other template which you can do as well, and we'll take a look at the a little bit later. And then we also want to iterate through a list of items so we're going to use our control of flow here to say, go ahead and bind to the template with the name "products template" which is down here in this scrip tag. And then iterate through-- on my view model, there's a lines property, it's actually an absorbable array, and we're going to iterate through that. So for every line item, we're going to spit out a row here at tr with all this of the content. But we're not done, we have a few things to fix up in the tr. Now in the tr itself, we can see I've got options that are being laid out with parent products. Now, I can't just say products because if I do that, the issue here is the data context gets a little skewed. So inside of the template itself, I'm going to scroll up here, we've got foreach lines, the data context becomes each line item. Line items don't have an observable array of products. And to prove that point, go back to the view model and here's our view model. It has line items, so inside the line items right here, you're inside this observable array, you don't have this products observable array. So we need to do is bump one level back up, go to the parent of the lines observable array so you get to the products. So that's one way to do it, we could say, I want to get from here up to there by doing parent. Or another way to do it is you could say, I want to get from here up to the root. And we could say root which is dollar sign root and then do products. So there's two ways to write this. We could say parent products or we could say root in this case. Now, root is nice because we know that this particular one hangs off of the root and I use that a lot myself. The parent's also good to if you know that you have to go multiple levels up. So you could actually go, let's say you're inside of a grandfather, grandfather to grandchild hierarchy, when you're down in the lowest layer, you can actually bump back up saying dollar sign parent dot parent dot products in that case. But here, we're going to use root products. Now the rest of this don't need that because inside of each line item, a line item has a product that its associate with, with a short description. And then all these other ones here are also associated with line items itself. The only thing inside of this template that's really not associated so far with the line item itself is the list of products, the thing that's going to low at our drop down list. Now, we also-- one other item we have to fix up, we have a remove button. Now the remove button is also inside the template for each line item. We want to, however, operate on the view model to call the remove. So I could look at the remove line function, it's in the view model itself. So once again, I could do a data bind opportunity here of-- let's set up a parent or root, wouldn't matter which one we do. And I'll only use parent this time, this root, to get the time, I could say root remove line. So we got that coming in here and I'm going to tell it what I'm going to bind to. So when we click, go ahead and call parent remove line. Now I would definitely recommend being consistent and if you're going to use root here, you might as well use root down there or use parent and parent. Now we have a few other things to clean up in here. Let's take a look at what we have. We've got our td up here for drop down. Inside of this td, we've got an image and then the product model, brand, and name, but we're not always going to have a product associated in this particular td because the product's not going to be there until somebody selects it from the drop down list, that's were the values bound to it. So, we really need to do is just not even bother with entering anything inside of this td. So all this (inaudible) and I didn't want them to be data bound or do anything if there is no product. So one way to do that is to say data bind and then here I can say if there's a product. So if there's a products, I'm going to highlight that there, if it's there's product, we're going to go ahead and handle executing up this code here. Now let's see if there's anything else we going to do. We've got a td down here showing the sales price of the products. So for that one, let's do the same thing, we'll data bind if there's a product. Down here, we're actually associating the-- to the view model itself, I'm not (inaudible) the line at them. So we're looking in here to see if there's a product, we're saying if it's visible, it is a product, show the quantity, and show the extended price. So let's run this guy and see what happen so far. Right now, we've got nothing showing and no line items. Now we have our product drop down. Notice nothing here is showing up. The first two guys are the ones we use at the if to say if there's a product, show the product and the price. For the quantity and the extended price, we use the visible binding. Now I loaded and selected this strap and I'm going to select multiple items, I can add another one, and we're all good to go. But this is a little inconsistent so there's another way to this. So, we could take the visibility here and we could turn that as well into a data bind if products. Maybe we don't want to show it in that case, and also for this guy. Now I'm copying that in four places. I actually don't want the td to be there, I just want the content to be there if the product doesn't exist. So let's run this one more time and we run this guy here, they share the same effect. Notice nothing shows up unless it's supposed to and we're good to go. And this shows how easy it is to take a set of HTML and create a template out of it and iterate through it using the foreach control flow bindings and also how to use the binding context like parent and root.
Anonymous/Inline Templates
Well, Knockout supports using script tags or templates like many of the other templating the engines, it also supports a native template engine built-in that you can do in line templates with, and the control of flow statements are really helpful in this case. So you're not going to reuse your templates a lot, there's no need to make a template and put in on a script tag and maybe stick another file or somewhat the other and of your HTML page. But the control of flow elements can really help you create an implicit template on the fly. So instead of having template here where I've got a name template and pointing to a script tag, I could instead use the foreach with the lines and actually put the template right in line with my t body. So that way, it's going to be creating anonymous implicit template inside. Knockout has a built-in native templating engine, and we've seen how you can use it in script tags and other elements like div inside of the dam, but it also allows you to create anonymous inline templates when you're using things like if, ifnot, with, or foreach. So by using the control of flow statements, these bindings, it allows you to basically create a shortcut to creating a template all by yourself, and it's an anonymous template. So all part of this native template engine built in on Knockout. And by using this, it allows you to remove any external dependency on templating engine such as jQuery templates or others like out there like Underscore. So let's see how does it works, so if you look at the if and ifnot 'cause they're based in the same syntax, we've got a template up here saying template if selected. That's really what's happening when you're using the if, but you don't have say template if selected. What you could do instead is just say if selected, and under the covers, it's going to create a template, an anonymous template with no name. So by using the ifnot shortcut, you have the same effect as well. So really, what you want to do say if colon is selected or whatever else you're going to do, you're actually creating a template and everything inside inline becomes the template for you. This is a great way to remove templates for you really don't need in a lot of cases. So without doing this structure, you could have actually created a template for the span element for the text name, but they're really even kind of overkill for just one element or just a few. So the if's and ifnot's, all this to control flow's are really nice for that. And here we can see that the foreach is basically performing an anonymous template for us. We could say template collon foreach, but instead the shortcut syntax which much rather use is foreach products which creates an iteration through all the products, and then the span basically becomes an anonymous template inside of there. That's great for something like an example we so with the tr in the previous example. So here we've got down below, we've got a with statement the we're going to create. Now you don't see with here because it's doing 3 things. This is the long syntax. Create a template, it's going to be the items in line here. We're going to creat a template and if there's a selected product, then pass in selected product. Well the shortcut for that is, with selected product, that's the same thing, miss a line above it. But in this case, we're saying with, it's going to create a template for us of the items inside the div, inside that container, it's going to perform an if to say, only do this if there is a selected product. And then the third step is it's going to pass in the instance in selected product using the data parameter in this particular case. So this is really a nice shortcut using the with. So we seen the if, the ifnot, and the foreach, how they're all shortcuts to creating templates. With that, let's take a look at a demo in how we can optimize our previous template using this new constructs.
Anonymous/Inline Templates: Demo
Inline anonymous templates are pretty to easy to create. So let's go ahead and look at the example 5 dash 04, inline templates, and show how we can take a template that is in a script tag and say names template. Take its content out, we'll actually delete the script tag. Let's move it up into the T body up here, we'll insert in there and let's format it. So we're just taking the content, we've moved it up, so were able to remove the script tag. Now let's take a look here and I'll actually copy this, just so we can see what it looks like before and after and we'll stick in some comments, if I can comment it properly, there we go. Now what we have before was a template, but we don't need the name anymore because it doesn't have a name. Its anonymous inline and we also don't need the tag there called template. So we've really been able to reduce that from template name, products temple foreach lines, down to simply foreach lines. So reducing it there, we've removed the script tag and we also get all the code to be inline now. So we don't need this T body, get rid of that as well. And now, we can look through the code and see that we have other control of flow constructs that we can apply here too. So we have the if statement that we saw in the previous example. Now, one of the problems with this if is that we have to repeat the word "product" here, here, here, here, lots of places. So that's the advantage using the with, and I can say with products which, in this case the with is saying, if their product exists, do this and now make the data context actually be the product. So I'm able now to remove the product from there, from the short description, for the title short description and I'm good to go. And I can also do the same concept down here in my model and my brand. If I wanted to get a little more creative, I could also do a data bind here and do a with statement for model, and then just remove the model from the name and brand and just make a little tidier to do. So with statements are nice way to kind of tidy up which you're working on. And then we can also do it down here if you wanted to for the product. It's not too much more code to put the with inside of this. Then the if and we can do it there. We don't need to do it here, in this case, 'cause we're not actually referring to any nested objects or properties down there, so we're good to go on this one. And actually, we wouldn't want to do here 'cause we did a with there. The problem is then there is no quantity property on the products. It's actually on the level above it on the line item. So we actually want the if in this case. So you've got to be careful where you use the if versus the with and make sure it's really applicable to the situation you're looking at. So let's go ahead and view this the browser and we run this and we show our products and when we select an item, we can see that everything is showing up properly, but when there's no item selected, notice everything is not being shown up and that's because the items are actually using the control flow to-- with the ifs and the withs to show what they show and not show what they shouldn't. And again, this template that were showing here, the eachline item is actually being used with the inline anonymous templates.
Dynamically Assigned Templates
( Pause ) Templates are good for all sorts of scenarios. For example, let's say you had a template for a summary of some product information. And you wanted to be able to swap from that to a details version on the template as well. So a user has a product-- full product summary they want to look at or just to see overall information of the product in a very brief glimpse and they click some other button to show the full details and it swaps up the template. It'd be very nice to be able to take that template and swap it out on demand and you can do that a couple different ways. One way is way called dynamically changing templates where you can swap out or you bind the name to the template with an observable. So in this case here, we've got our template name which is set to template choice, but notice there's no quotes around template choice. That means template choice is actually a property on one of our objects. In this, it could be unobservable or it could just be a regular property depending upon what you needs are. Observable again will listen for the notification changes. But here we've got the template, it's going to be named whatever the property value is for template choice. And then we have two other templates to find in our file here, we've got template summering, template details in different script tags. So in this case, somebody's going to click some kind of a user input and when that user input changed, we could change the value of template choice to be either template details or template summary. And that's the value that will dynamically flip flop the template for us. So that's one way to do it and you could of course load this script tag templates from other files you want using Ajax, doing some kind of call with Ajax or with the jQuery helpers that they have for it as well. Another way to do it is through control of flow. So if you have your two sections on your page already, either using templates or maybe some divs or something else like that, you could use if and ifnot bindings to toggle the templates. So when somebody changes, if they want to show details or summary, you could just simply say, for this particular template, go ahead and (inaudible). Say if not show the details, and the other one you'd say, if show the details. Alternatively, you can make them both be ifs and then you just put a bang in front the show details as well. So in this case, the show details is just an observable and set to a true or false value. Let's take a look at how these work in the examples.
Dynamically Assigned Templates: Demo
( Pause ) We're going to demonstrate two things in this example. First, we're going to show how we can swap between two different templates, and then second, we're gong to show how we can select an item and then show the details for it. First, to swap between the templates, we want to change this template binding up here first from hard coded value of product summary which going to point to this script ID template. And we need to change that so it can be dynamic. So we'll need a property name here instead, 'cause right now if I've run this, we'll just show you real quick what happens. When I run this guy, and I select somebody, I check this box, it's not changing the view. I want this template here to change every time I check on this box. So what I'm going to do is I'm going to remove that hard coded value, put in something called product view and this is going to be property down in my view model. And I want to swap that value of the property to be the product summery or a product details. So let me go back to my view model. And in here, let me type in product view, product view, and I could make a natural value like, you know, product law or whatever I want to call it. But what I'm actually going to do here is I want it to be a function to figure out which value do I want to show there. So it's going to be a function and it's going to return the value of something, we'll put "something" there for now as a place holder. When something happens, I want to say, make it product details, otherwise, let's make it product summary. So this will be product summary. And these are the names of the templates right here. So you have product details, product summary, we're going to make sure that's the name, product summary, product details. Good to go. Now, the "something" is what is-- that going to be the impetus that actually drives the changing of the value for the template name, and that's why we have that check box on the other screen. So in that check box, if I search for it, I've got my show details right up there, I have this bound to a value called show details. So what I really want to do is not do something. If show details, I know it's a observable in this case right down here, if show details is true, show the details, otherwise, show product summary. And because it isn't a revealing module pattern, (inaudible) here is telling me that that's not exposed, publicly yet. So I'm going to come down here and I'm going to add it as an exposed property and I could rename it something else here like Fu, but we're not going to. And then I'll make sure that it's mashed up there. Now when I ran this, I should be able to dynamically swap between the templates. (Inaudible) When I click on it, here's the other template. When I click on the Taylor Guitar, expand the template, there it is. I could click on different guys and there's all good to go. Now we want to handle how would we select an item. And for that, we've got some code in here that's handling it for us so if we look for "is selected" 'cause it's already being selected for us. For every item in the products, basically I'm going to change the class name using the CSS binding type to be selected whenever the "is selected" property is true. So that means it's probably "is selected" on each products and there is. So if the product is selected, we'll going to change the class to selected. And the selectable class is always there, that's when we hover of it. Let's see how this works first and we'll actually dive into code there. So here is the CSS class that's hard coded to it for the hover, that's the selectable, that's this class here. And then when I select the item, it turns black. And that CSS class is selected and in only gets turned on when "is selected" is set to true. So how do we actually set "is selected"? That's the key. So if we look around, we can see that there's whoops-- we can that there's the "is selected" property here, it's the only place in the HTML that's doing that. How are we handling this? When it's clicked in the div, we're going back to the root of my view model and we're calling a function called select product. So select product in the view model is going to accept the item that's been clicked, it's going to then say, all right, say, call selected product, the selected product is the function which is the observable and it's going to set it to be that ID. So here we've got select product which is going to be called in as the method and it's going to set the selected product for us. So how does that do anything? It's not actually setting any observables inside the product itself, but the key is the product function. So when I create my product models, I'm not only just setting all properties, I'm passing in the selected item. That selected item gets passed in and then "is selected" function becomes a computed method. It could be a dependent observable basically, where the selected item is being compared against itself. So if the item that's been selected back in the view model is equal to this particular product, that's going to return true. So if we take a look at how we'd search for the new which should be down in the load, when we load up our view model with our products, you are pushing our items in. We're saying, new product, selected products. So we're passing in that selected product which is right up here or passing in that guy and when ever he changes, that means he's going to compared in that computed to the current product and if that's true, that particular product will then be have (inaudible) is selected value true, all the other ones would be false. So again, when that happens and we run our code which you can't run it from there, you've got to go to your HTML. When you do this and you click on that guy right there, what's actually happening is we're setting the selected product and then were calling that method, we're just going to set that property to observable. It's then going to compare itself inside the product object itself and say, is the selected product equal to me, to self, and if it is, it's true, therefore, the class turns black. And that's just a really easy way to select an item and show the selected item on the screen, which is a nice little tip.
Swap Templates with Control of Flow: Demo
In the previous example, we saw how we could dynamically swap out templates by making the template name actually be a property. In this example, we're going to show you how we don't need to make a template name, we could actually just use if and ifnot, the conditional control of flow, to actually help us to show templates. So in this case, we have an item here that we're going to show up on the screen, a bunch of items, and when we actually select an item, we want to show either the summary of the details. Right now, we're showing both the summary and the details in two different divs. So you want to hide one div and show the other. So first, we've got our selected item and once the item has been selected, we want to show either this div here which has got my selected product and this one will be the actual details and then we've got another div right above it which is going to contain the summary. So here's my summary div. And what can I do is I can stick in a binding here and I can say, if, and then we can set a property up here so we have us some property that tell us are the details being shown or not. If they're trying to show the details and that's going to be check box up here, if you're trying to show the details, then you want to show this one or do you want to do ifnot. So if it's not the details here, because this one is going to be the summary, we're going to do this, and then down here, we're going to do if it's going to be show details, we're going to show this guy. So now, when we run this, we're basically just using the control of flow to handle which item is going to be shown. Notice it's the summary mode, just showing the brand and the model. I'm going to show the details, it's showing all the information including the picture based from the item, and I can toggle that on and off. Now if you don't like ifnot and if, what you could do is just use the if up here with (inaudible) your details, which I personally feel is a little more readable. So we ran this, that should also work for us, and we can see when I check the box that everything is good to go. And that's how you can use the conditional control of flow to toggle templates.
Template Binding Parameters and Array Filtering
There are series of parameters that you can pass when you create a template to define how that template should behave. These template parameters are name for each data after render, after add, and before remove. Name is obvious, it's the idea, that element, that we've been using to define the template and the name could be the ID or we also saw how name could be a property that comes out JSON object. Foreach is something that let's you render through the template in foreach mode. Basically iterating through a series of items, in array or observable array, we saw that as well. Data allows you to override the context for the item that's being passed in so you could be a looping through a list of products that maybe you don't want the data to be each individual product, it can be something else. So data is a way you can override that. Normally we don't do that, that's more for Edge cases where you need to specifically override the data. If you don't specify a data because it is optional, it becomes-- in foreach mode, it becomes the individual item that you're iterating through. So again, for products array, it become each individual product. And then we've got three that kind of-- are more behavioral, like after render, after add, and before remove. And these are callbacks that you can define, functions that are invoked at certain points when the template is being rendered. So the after render is a callback that's invoked after the (inaudible) elements are rendered. So if you wanted to do something after the templates are rendered, here's where you can do that, it's your hook into that event. There's also an event basically for the after add and before remove and we're going to take a closer look at those. So with these binding helpers here, we can see that we've got a ul that's using a data binding template, and the template's defining that we're going to have items in here from a template named friends template. So there's probably some LI templates somewhere called friends templates that's got all the list items we're going to use, and the foreach mode is going to go through all the model friends. So we're going to list out all the friends in that array and then data is-- not specifies, the day is going to be each individual friend in that array or whatever object happens to be inside the friends array. And then before remove, we're going to call a function and that function is going to perform the jQuery slide up on the element. So it's going to put a little animation in there. And then after we add it, it's going to do a little bit of slide down, it's going to hide it. So we're going to do a little animation here. Now, I don't really like doing this code inline, so an option I like to do, is to move this callback into the view model itself. So instead of putting the full function out here, you can actually move that code into the view model and just expose methods, function, in view the monocle to show animation and hide animation or whatever you want to call them, and that just a (inaudible) clear way to do it. Let's take a look at an example.
Template Binding Parameters and Array Filtering: Demo
In this example, we're going to add the behavior to show some kind of animation before something's removed and after something's added to our template. And we're going to use the afterAdd and beforeRemove template parameters to that. We have a couple of things we have to set up before we can get there. First, we have to have some kind of a check box to toggle on, do want to show all the items or just some of them? And we're going to toggle based from one of the items actually of type guitar. So first we're going to need some kind of a check box. So let's go ahead and add a check box to our page. First, we'll add a div, and this is inside of example 5 dash 07 after add. And then inside the div, we're going to create input and we're going to sneak that input be of type check box, and then we're going to make this one do a data bind operation on a property which we'll have to define and we're going to set the check binding to show all. So do you want to show it all or don't you want to it, and we can kind of set this up. And then we want some text messages as well, so let's create a text that says all products. Now if we run this, correct this just to make sure we're signed up, and it works. Here, we've got our items up there and it's probably breaking because show all doesn't exist and it doesn't, which is fine, but that's the check box. The idea is we click on this and it's going to show only the-- it's going to shows all the products. And when it's not checked, it's only going to show the guitars. Next, we have a little bit more to change the HTML, not much. Right here, we've got the foreach for the products and we actually have changed this to be the full blown version of the templates syntax. I mentioned before, you could actually do the same thing by using that syntax. Now we want to do this because we want to add it in the additional parameters as well. So let's add in after add, that binding parameter, and we'll set that to be show products and let's set the other one to be to beforeRemove, and we'll set that to hide products. Now obviously, we're going to need to create the properties on our view model that support this, if we could just indent a little bit, show it a little bit better, and the class down there. So here we can see the template is set up to be an anonymous template because it's the content inside of the ul, doesn't have a name, it's doing foreach (inaudible) products and afterAdd, it's going to call something called show products and before remove, it's going to call hide products. One other change we're going to have to make is when we click on show all to show all, we want the product array dictate all the products, but when we uncheck that, we want it to only show the products that have typed guitar. Well the products array, we could tinker with that if we wanted to and use some kind of visibility inside of the list item to turn it on or off base from it's a guitar, but it-- wouldn't it be better if we had a way to actually define the array to only have a (inaudible) that we need. So (inaudible) on the second observable array, one called products to show and that's what's going to be bound there. So we've created four things that we have to define back in our view model, show all, an array property we're going to use to show the products, and then the show products and hide products and methods that we're going to have to create. Let's go create those now, we can see the products are there, let's add a property for show all and we'll make this an observable and we're not going to set the value by default yet then we want to expose this though, so let's go ahead and expose that through our view model. And then we need to determine if the product is a guitar. So on the product object, I can create an observable or a property or a function, this case I'm going to create an is guitar property. And the is guitar is going to take to shape of a computed. And I like using the computed here 'cause you have to figure out is it guitar, isn't it, and the computed is going to determine through a function, whether it's a guitar or not by bit looking at the category. So I can say return, now if the category is a list category, and to use this, you actually have to put the owner in here, so the owner is (inaudible) passed in the computed, which becomes self. And then that represents-- this then represents self. So I can see this category, and if it exist, go ahead and evaluate the category, and if that category's value-- actually it's category ID, if the value is equal to 1, that's a guitar, otherwise, it's not. And then if there's no category, it returns false. So now we've got our observable set up here, our computed, for is guitar, now we need to take advantage of it and use it down on our view model. So right effort show all, let's add in the products to show observable. And this is going to be another computed so I'll create computed here and it's going to take the shape of a function, and you got him all set up. Now we have to determine the logic. Couple ways to do this, we're going to do if show all, we're looking at the value, and for showing all, then we're just going to return back products, we're going to cheat. You know what? Only thing I need in this case is products so let's go ahead and return them. But if something else is the case where it's not show all, I could use the L statement if I wanted to, but that's not into here, and then we're going to say, ko utils array filter, I could use some jQuery function right through here if I wanted to, but what I would like to do is use the array filter which is a nice handy function built into Knockout. And then I'm going to loop through all the products, and these function here, is going to take P as its parameter. And P's going to represent each product in the products array. And for if function, I'm going to return back simply if P is guitar, and that's going to determine if which elements are going to be returned or not. So the array we'd filter is basely saying loop through this array and execute this function and if it's a guitar, return that item, if its not, don't return that item. So now we've got products to show all set up, and now we need to return products to show to make it publicly accessible, I'm thinking we could rename the function here. We'd like to, now it's not going to run yet because we haven't written the hide or show, so lets get rid of those and just make sure that the products to show works, which we're going to view in the browser? And we can see here, they're just instantly appearing and disappearing and it all seems to work but we need to have that behavior in there for hiding and showing, so after add show products, before remove high products. Let's go ahead and add those functions we'll start out by writing the show products, and for show products, we're going to set this equal to a function, and function is going to accept in the element that we've clicked on or that's going to be hidden or shown, and for that element, we want to determine if the element no type is equal to one, then we're going to operate on it, and if its equal to one and we trying to show it, we're going to use jQuery to find that element, and at first we're going to hide it, and then we're going to slide it down, it's the reason we built of jQuery functions to handle-- hiding it first which just can set the display off, and then slide it down and animate it into the place. Now the high products is going to work similarly, so to hide products equals a function, we're going to pass the element and it's ELEM, and that function is going to also check if the no type is equal to one, so I'm going to cheat, just copy and paste, and the syntax is very similar, so if the no type is equal to 1, this case, you don't want to hide it and slide it down, we want to find that element and we're trying to hide it. First, slide it up, so again we're going to use the jQuery function, (inaudible) sets a show on me and when I slide it up, I want to call this other function when it's done, and that function I want to take, just put our enter in there, I want to take and find that element and then when it's done, I want to actually remove it, so I'm just running a little syntax in there, that's how I want to animate, I want to show my products to be exposed, show products, and I also got my hide products, and I kind of show him through there. Now we take this and we run it to the browser and we click on all, and so they animate into place, and they slide back out of place, so now the before and after are working really nice for me, and I've implemented the array filter to go ahead and filter out all the items that are not guitars or are guitars based upon what the user selected. I'm just taking advantage of 2 jQuery functions to actually do that animation for me. But there is to it.
Containerless (Comment) Bindings
Knockout 2.0 introduced a concept called containerless bindings which is basically a comment syntax that Knockout uses and to help you render templates on the fly. This works really well with the control of flow bindings, if, if not, for each, and with, and template. So how does this work and where would you want to use it? To understand that more, first you can understand that it's not the standard binding that you use where you have like a div or a script tag. So you're not going to have that standard data dash bind in there. Instead, you're going to have a template that you've created in the fly using this containerless control of flow. So no, I'm not nuts, it's basically a template without having a template, and they're supported with the if, if not, for each, with, control of flow, and also of course the template binding that we have, and it's all part of the Knockout native template engine that's supported. So let's take a quick look at an example here. Now normally, we could have like a div that surrounds the span on the input just to wrap these 2, and the div may not serve any structural purpose, so with previous versions of Knockout, you had to had like a div around this or some kind of a container element, and then setup the data binding, to use a with and select a person, and remember the with is technically just a template under the covers as well. So now with 2.0, with the containerless binding, and you can use the syntax here, create a HTML comment, then prefix it with KO, and then everything inside it is blocked until the slash KO is going to operate inside the with. So this creates an anonymous template on the fly and you use the with operator on the selected person, which is pretty cool. Now here's another example where you can do it for each. This comes in really handy when you've got like an-- a list where you want to create a list of items and you want to iterate through them, maybe it's a list of acoustic products or some kind of guitars you have and for every product, you want to list out a list item, but maybe you want the first item in that list to have a different setting, and maybe static text (inaudible) like acoustic guitars as the title. So one way to do that or if you want to setup separate items of loops in here. One way to do that is to create this containerless binding. Now without this, you'd have to find a way to create some kind of an arbitrary element inside of here maybe a sublist item or something, where you'd have to create that. But you can see how this is a little bit easier to use when you don't necessarily want to create an element that not necessarily serve any purpose other that helping Knockout. So this is a great way to reduce unneeded elements inside for HTML, which is awesome, and it moves the binding logic outside of elements. So some people don't like having the data dash bind inside of their elements especially for control of flow and this basically takes that control of flow outside of those data dash bind elements and makes it less obtrusive by putting it in its own comet-based elements. Let's take a look as some demos and how this works.
Containerless (Comment) Bindings: Demo
In this example, we're going to show how containerless bindings can help alleviate some of the markup that you have to write when doing Knockout bindings. There's a lot advantages to having containerless bindings. One of which is you don't need to create markup just to have a binding operation. For example, sometimes you're going to have to create a div or you want to create a div just to actually wrap other bindings together, and by using containerless bindings, won't have to create a div to do something like that. So just to show how that works, first we're go on and create a comment down here and a comment basically becomes the binding operation that we have inside of the well. So we're just actually going to actually take that data binding operation out, copy it, and paste it down here and we can eliminate the data binding from up here and voila, so now we have a UL class list, and then we have our binding operation. If you like we can stretch it a lot to one line just to show what it looks like and there we go. So basically it's just a comment that starts at the binding and then everything inside of there is what's wrapping up the containerless binding operation. So now we can just end that block and everything between the beginning and the end of that block is inside of that template. So we've got some data binding down here in the div and let's say I wanted to move that out to a containerless binding, and now we can create a containerless binding, where I would just say if show details-- I'm sorry if not show details, and we don't necessarily need this particular data bind operation to be there. So we're going to go ahead and get rid of that div. Now, let's scroll down the matching div that we have for him and that matching div should be right there. So we don't need that div anymore either. Now notice before what we had is we had a div that was really only serving that purpose of wrapping up this other div inside here. So we got a div inside a div, and the outer div was really just managing the data binding operation which we didn't really need. So now it's very clear that we've got that div and it's only like one outer container. Now it's really the same situation down here of the if show details, again here's the div that starts. Let's close it's inner div, and you notice it's just a div that's wrapping up another div, which is kind of silly. So we're just going to go ahead and now and say KO, and we'll copy and paste, hopefully no copy paste bugs, and we'll wrap that guy up and again, let's go ahead and find the lower div, we'll stick in our ending block. We don't need the outer div anymore. So now, we've got our inner div, which is wrapped inside of this statement. We got another div there. We can move him back, and all the indentations are working just fine for us. So are there any other places in here we could-- we could take binding out, one of them we can see is kind of embedded up in this class, and this div actually serves a purpose, and it's wrapping up the product detail's area, but it's a got a class of left float on there. But if we want, what we could do is just move the operation for the data binding out, and stick it up inside of a containerless binding, and we can do that pretty simply just by saying KO, and then we say if, selected products, and we're good there and we have to put our endBlock in. Always remember your endBlocks. Now this-- we seen here this works with ifs, it also works with if not. It works with template or with for, each, and with, as well. So you got those 5 control of flow bindings it works with, so like right here, we've got an if with the bang, on the show details, we could have instead done if not show details. That'll work too. I kind of like the bangs and text better. But let's run this and see what it happens. We expect where we've got our items, we're selecting them and we change the item here, notice that the details are changing too? Easier to see with the picture, and it's all good to go. So very simple change of code, no JavaScript changes and then, actually I like this because of its syntax highlighting, shows you very clearly where all the Knockout bindings are for control of flow using the HTML comments syntax.
External Templates
There are lot of usual scenarios at Knockout where you may want to pull in a template from another place. For example you want to pull your templates out of script tags or not even have them in the flow of your document using containerless bindings, but instead have them in a separate file and there's couple of ways you can do that. Some of which you might tackle are similar to technique here used by Ryan Niemeyer on his Knock Me Out blog where we mentions a couple of different options that you have. Here's a very simple example where you can basically go out and use Ajax to load a template where you give it a name, you passage a specific URL to find it and then it's basically just appends it to the body of your HTML and sticks in the script tag and gives it an ID. Notice that the end of this-- something a little funky here where we have to do is based upon the number of templates you have, once you actually load all of them, then you actually apply the bindings for Knockout. And what happens if maybe one of them fails or doesn't load or something else, there's a couple of other error conditions that you probably have to handle here. So it's not as robust as we want and Ryan even admits that in this page here, he's got some other options that you can load down below. But there's another option that I want to explore here, and that's by a guy named Jim Cowart who actually was helped by Ryan Niemeyer to create a plug-in for Knockout called the Knockout External Templating Engine. It always allows you to stick your templates in an external file, and then go retrieve those templates on the fly using this engine. And all you have to do is basically drag this guy in to your project and it shows you here which pre-requisites are, and all you have to do is drag in this particular JS file unto your project. And technically, you don't have set any of the properties. So in JavaScript, they usually set the suffix, they set the URL, where to find my templates, and then you can also override the loading content which is basically what's going to display in the HTML while the templates loading. So there's some options you could do as well, but what's really nice about this is it plugs right in to the native templating engine of Knockout, works great with it and it doesn't change the other behavior of the templating engine. So let's take a look at how this works and how simple it can be.
External Templates: Demo
The Knockout External Templating Engine could be found here at this URL, and then you can download it off of GitHub. So let's get out of the magnifier and we'll show you where that is. If you click on the Downloads for GitHub, you'll see here that you can download the entire file as a zip. I've already done to save some time here so we can click on the Downloads and I've expanded them all into this folder. So looking at here in the lid folder, we can see that I've got these 3 all files, let's go ahead and copy them into the script's folder of our project, and we can see them right there, and it's going to our 5 dash 09 external HTML, and we're going to actually drag in the all file. Now if you're doing production, I would use the minified version but because I want to get the syntax and I want to be able to look to the code, I'm actually going to use the blown up version in this case. It's 13k for the blown up version, I think its 2k for the-- or 6k for the minified version. And then inside the JavaScript, we're going to set some properties. You don't have to do this but I like to use some of the defaults that they have, so the template suffix, I'm going to setup to be anything that ends with temple HTML. Basically all my templates, that's why I don't have to say that the full name of the file that I'm going to refer to, and actually going to assume everything's going to have that template suffix, and then I can set the template URL for everybody to be in slash templates. So I'm going to have a folder called templates and let's make sure I've got that in my project. So if I look over here in the project, we've got templates and we've got a couple are here already, products' details and products' summary. If you open those files, there's nothing in them. I just (inaudible) the files for now. We'll take advantage of those in a minute. You can override those properties too, the JavaScript properties inside of each individual template. Let's go and check out some templates and let's go ahead and convert them. Let's start by taking the product summary here, which you can notice I've got a script tag, which has got a template and it is being refereed to with the ProductView. ProductView is going to dynamically toggle between the product summary and the product details. We can see there's a property called ProductView, and it's going to toggle between product details and summary. So what we want to do is take this script code out. Let's take that script code out for product summary. We'll stick it inside of this template, and we'll just let's just left justify it. Let's go back and I'll just do the same thing for the product details. So this has got a little bit more code, and I'll just pull that into the product details template, and have we'll left justify it. Now let's close those down 'cause we don't need to look at them anymore, and up here we should have a couple of empty script tags which we do, and we don't need those anymore. So we've just cut out a ton of template files in there which we don't need to go use, and then ProductView based on what the user selects. I'm going to toggle between this two. Notice I don't have to change anything else about this template. The name is still going to be either product summary or product details which is going to match the name of the prefixes file over here, and it's going append template HTML, and it knows where to look for it because we have a URL, which is pretty good to go. And just to make sure we know that it's not going to screw up any of the other templates we have built into here. Notice we've got this products list template which is in a script tag, which we'll just leave down here for now just to show it doesn't get ruined and we still have a template up here that's referring to it. Of course, we could move that out or put it in line too, but let's run this and see what happens. I run this guy here, we should be able to re-select the guy, see the summary and the details and those are pulling in the templates. If we open up the browser's tools in the network, we can see if I refresh the page, here is the request, it's going out and getting the templating engine, and when I select an item, you can see down below, it's actually got those templates one at a time. First they got the part summary then the details. Show it one more time, if I click on the item, notice that only had the summary template, and when I click on the expand details, it then and goes and gets out the product details template. So that's pretty slick, but there's other things we could do too with the templates. I started out with 103 lines of HTML, I'm down to 66. I could also take the header and pull that out, and put it to a template. Notice every page that I had had a header in there, so what am I talking about? Up here, I've got this content which has a title and then index John Papa, in the bottom, I'll show you the example of what this particular demo is exploring at the footer. So we can pull those out and make templates out of those too. To do that, let's go ahead and wrap up what's going to be the header, that's right there and let's create a template tag and we'll use the containerless tags to do that. I'll say it's going to be a template, the name of this template is-- now let's just call it header, and now we're actually going to override the template URL because, just to show you how to do this, we can actually stick these into another folder, not just templates but let's stick it into metadata folder. So we'll put this one in a sub-folder called metadata, and that template should be good. Then here, oops, we're going to go ahead and put the endBlock and then we're going to take this content. We're just going to rip it out of there, and we're going to go over to the metadata folder inside the header template, I'm going to paste that code in, left justify it, and that guy is good to go. And we're going to do the same kind of thing with the footer, so let's grab that same syntax and I've got a footer down here with my KO with metadata, and instead of doing KO with metadata, what I could do instead is change this to a template. I'm going to call this guy "Topics" 'cause that's what we're talking about and the template URL is going to again be metadata. And I also want to pass in, see I've got this with metadata down here, I want to pass in the data for that. So I'm going to pass in this property called metadata for data, so I could get rid of that with block entirely. And then I got to take these topics, pull them out and I got to stick it into my topics template, and that's good to go. So where is that topics coming from? We see (inaudible) topics, if you look in the external JS file, you might have noticed all the view models at the top have like page titles, personal informations, (inaudible) for the header, and the topics are, what topics does this demo go over, it's just an array of items that can get looped through. So when I run this now, we should be able to see all the templates at our working force. First, as the page loads, let's go and refresh, we can see down near the header template and topics, and we pull in those guys each. Now we click on the items and the other templates are getting loaded on the fly as needed. So everything works just great for us, and the net result is the templates are pulling only as needed and now my lines code are down to 55, which of course I could get rid of these 5 as well if I wanted to. But I've cut my lines code into half (inaudible) file, I've really moved out in modular as my templates. I could reuse these in other places too, and it all doesn't interfere with your JavaScript at all, other than adding in some defaults if you want to use those. So it's really nice, it bakes right into the native template engine, and this is the function out here that you get when you use the Knockout External Templating Engine that's written by Jim Cowart.
Summary and Tips
In this module, we looked at a lot of different ways you can handle templating. We started out by looking at the native template engine and looked at name templates and anonymous inline templates. I prefer to use the anonymous inline templates anytime that I have a template that's going to be used once inside of a page, and the named templates are nice when you want to use external files. We also take control flow with the 5 different constructs if, if not, with, for, each, and template which are used quite often. In the binding context, which are very helpful for navigating up and down the chain, which are kind of similar to the same old technology's RelativeSource ancestor binding. They help you get right to the roof of view model if you need to. We also looked at how you can (inaudible) choose a template by setting the name property of the template to a property. It could be observable, or a function or anything, it doesn't have to be observable in this case, but it could be any kind of property where you can toggle the template dynamically, which is pretty cool. In table binding helpers, we can pass in a different data context for the template, the name of course or you could leave a name out if it's anonymous. You can also use the for, each, and then the after and before remove, to do a little animation on adding and removing template items. And then we took a look at the containerless kind of binds which is one of my favorite features of templates where you have an anonymous inline template that's using the feature up here, that's using the control of flow at the for, each, and it's anonymous template is really got the template syntax, which is under the covers (inaudible) template without a name, doing a for each pseudo products and you can just basically create an inline block through the HTML comments and it takes that binding right out of your HTML and puts it, out of your (inaudible) and puts it into a comment tag, which is easier to see. And finally we looked at a nice little template which is run by Jim Cowart and was helped up by Ryan Niemeyer where it's called the Knockout External Templates, and here's the link for that. We showed how you can use that to dynamically link in external template files and pull them into your project as you need them which really is a nice way to go. So we looked at a lot of different ways to do templating, what do I prefer? I like to use the anonymous in my templates with the comment syntax when I have inline templates, and when I pull templates in from other files, I often consider doing that when I have templates, I'm going to be reusing quite often. So I like to use the first technique with the inline templates combined with the containerless comments, and then also use external templates with this plug-in when I'm pulling templates in from other places.
Custom Binding Handlers and Persisting Data
Custom Binding Handlers and Persisting Data
In this module, we're going to show you a lot of things that kind of put a bow around Knockout and put it all together for you. We're going to start off by looking at some custom binding handlers. What they do for you is they allow you to extend and create more built-in binding types, more binding types to the built-in binding types that exist that exist already in Knockout, and they're really handy for doing things like integrating with jQuery UI and other libraries or putting animations into your applications. Next we'll look at unobtrusive JavaScript, which enables you to pull some of the data binding syntax out of your html and move it over to JavaScript, which some people really like, and then saving and loading data. While this isn't a Knockout feature so much, it's nice to show an end to end solution, which allows you to pull data in from AJAX and then save it as well. And then we'll take a look at some other features such as how to do change tracking in Knockout and how to do mapping of objects with Knockout, and these are both available on NuGet. So with that, let's dig right in.
Custom Binding Handlers
Perhaps one of the most exciting parts of Knockout are actually the custom binding handlers. Well, what are these things? They're just another binding. So if you can't find the right built-in binding that you need for your situation, you can make your own. For example, you can create like a fade visible built-in binding to animate transitions for items to pop in and out, or if you want to integrate with something like jQuery UI or another library, you could create your own bindings to hook into like jQuery's button, jQuery Y's button. And we've got some other samples we're going to show as well, such as creating star ratings as opposed to just having numeric values. When you create a custom binding, what you're actually doing is you're extending onto the binding handler's object in Knockout and then creating your own name, such as fade visible, shown here, and then you set up an init and an update function. The init function is going to run the first time the binding is evaluated. So whenever you apply this fade visible binding, the init's going to run right away, and then every subsequent time that you have observable changes inside of the function, the update's going to run. So you're going to stick observables very likely inside of these functions and perform operations on them, and whenever those observables change, that's when the update's going to run.. So what goes inside of these bindings? Inside of the custom bindings, you have 4 different parameters that you can use, and some of these are optional. You don't always need to use all of them, but the first one is the element. That's the element that you're actually bound to. So quite often you're going to want to know what element was I on? For example, if I'm going to do a fade visible operation, I'd want to know which element in the DOM that I want to operate on so then I can maybe I can wrap it in something like jQuery so I can do something like toggling the visibility. The value accessor is what is passed to the binding. So when you say fade visible colon and then the value that you're going to bind to it, this is where you get the value accessor. It's how you get the value that you're binding to your custom binding. The all bindings accessor allows you to access other bindings on the same data dash bind element inside your DOM element. So, for example, if you had fade visible, and you set to a value like true or false on some observable and you had other properties like set duration for how long you want to take to slowly fade in or slowly fade out, you could actually get to that value through the all bindings accessor. And then the view model is just a nice easy shortcut way to actually specify the view model for the context of what you're going to be binding to. Now I always use the element and value accessor, but I don't always use the all bindings and the view model. So with that, let's take a look at a couple of examples of how we can bind up and create several different custom binding handlers and where they might be useful.
Binding Handler for jQuery Animation: fadeVisible Demo
Let's take a look of an example of how we create the fade visible binding handler. Here we'll click on the demo, and the starter has a list of products, and we click on the product, and you want the product to appear and the details and then also start to fade in slowly, and then we're also going to have a close button up here so you can close it and have it fade out. Right now it just pops into place, and there's no way to close it. So let's take a look at how we can do this. First we need to add the fade visible binding handler. So to do that, we're going to go down and create inside of the JsFolder a binding handler dot js file. Now let's start coding this, and then I'll do a copy and paste because you don't want to watch me type too much, but here we have the binding handlers with our syntax. We can type in the name of our binding handler, and we're going to call it fade visible, ok, it's going to be taking an object literal. So that object literal's going to have an init function, and that init function is going to have some values for parameters like elements and value accessor, and these are conventions that we use to create these, and then we're going to have some values that actually occur in there, and then there's going to be an update function, too. So I copy and paste, and then we'll write update (if I could spell that) and then we've got the update good, and we might actually take advantage of the all bindings accessor. So I'm actually going to add that one in here. So what I want my fade visible to do is I want as soon as the guy is kicked off, I want them first place to go ahead and just toggle the visibility. So first, let's just create a variable called should display or not, and we'll get the value of the value accessor, and remember, it's an observable. So we're going to use a parentheses at the end of it, and then let's go ahead and wrap the element that we have coming in as a parameter with jQuery so you can get access to it, and then we'll call the toggle function using should display. So then first state it's going to toggle the visibility automatically for us. And then we're going to do something similar down below. We're still going to use on every time the value accessor changes or any of the observables change inside of here, we're going to go ahead and fire up this update. So first thing we want to do is we're going to get him. We also want to get the all bindings accessor (let's call it all bindings) and we'll set that equal to the all bindings accessor variable up here, and I also want to set in a duration variable. So the duration's going to be how long is it going to take for it to bind in, you know, to fade in using milliseconds. So we've got the all bindings accessor. Actually we're just going to do all bindings, and then on there, we're going to have a variable called fade duration, and if nobody passes one in, we'll just set it to 500 milliseconds. That way it's really optional. So we're good to go so far. Now we actually have to do something to make it work. So we're going to set the should display, and if it's true, we want to go ahead and toggle the visibility using the fading. So we're going to say take that element, and we're going to call the fade in function using jQuery, and we're going to set it using the duration. So that's going to be the speed that we're using. If it doesn't exist and then we're going to go ahead and, again, pull on the element, and we're going to do fade out on the duration. So what we've done here is we've just written a binding handler that's going to hook up automatically for us based upon the values that are passed into the fade visible, and it's going to bind to that object, and then if somebody passes in a duration, we're going to use that for the milliseconds to do the binding. Next we're going to go create a template that we're going to use this fade visible for. So inside of our main html page, right here we have the class, and then we've got a template we're using called product details. Let's not change that one. Let's create a new one. We'll call it with fade, and let's go ahead and create a new template. So here's our templates. We'll copy the product details, we'll paste it, and we'll come over here, and we'll call it with fade, and let's add some extra features to it. So in here, we've got our basic data that we're going to wire up, but let's also add in a close button at the top, and I'm going to copy and paste this just to make life a little easier, and here I've just got a style that I've created called dialogue title border. It's just some basic styling with CSS, and then I've got a close icon, which is in your project, and when somebody clicks that close button, I want to go to the parent, my view model parent, and call the close details function. So we know we need to go and add this function now for close details. So let's go do that inside of our JavaScript. So in the JavaScript here for the view model, I'm going to add a new function called close details, and close details is wired up there quickly. It's not used yet. All we simply want to do is close out the dialogue when this happens, and we're just going to basically set a observable that we're going to create called can show details to false when this happens. So we're going to toggle a value called can do details. So let's create an observable for that as well. It's just a little trick to use, and by default, are we showing the details? No, we're not. So this variable is going to be bound to our template to say do we show things or don't we show things, and then the close details will be the way that we can toggle it on or off. It's just an excellent trick we have, and then we want to expose down below the can show details, and we'll also expose the close details down here. So we've got our two functions wired up, and what's going to activate this is any time we select a product, so right here in select product, after we select it, we want to go ahead and set the can show details to true. Finally, now we have to go back into our html, and then we can see that we're now using that template, but we have to wire up the fade visibility. Now we could put this in a couple of places, but let's go ahead and put it right on the main dip, into our main container. We'll add a data bind element here, and let's just set the fade visible (this is our own custom binding handler) and well set it to be can show details. All right? Got to spell it properly. This div here is going to use the fade visible binding based upon the value of can show details, and by default, it's false, and then it turns true whenever an item has been selected, which will then go out and get this template and bind itself up, and before we can run, we need to come up and add our binding handler JavaScript file in here, include it in the script, which we can do pretty simply. Now we've got him. We're good. Now we should be able to go back to our browser. We'll run the sample again. Let's just refresh, make sure it didn't cache, and select an item, and we can see a fade coming into play. I want to click here, it fades out, and if that's a little too subtle, we can come down into our fade visible, and we can set another property on here because remember, we created another property called fade duration, and let's set that to something a little more obnoxious, like 2 seconds, and we come back in here. Let's refresh the page, and that gives a very slow and subtle fade coming in, and when I click on here, it's going to fade back out, and that's all happening because of the binding handler. Right here we've got the all bindings accessor. So we grab the all bindings. It had a fade duration on there. It existed. So we're grabbing those 2000 milliseconds. If it didn't exist, we're using 500 milliseconds, and that's how easy it is to create custom binding handlers.
jQuery UI Button Binding Handler Demo
Let's show an example of how to create a custom binding handler to deal with hooking into jQuery Y. First, you're going to want to go ahead and download jQuery UI and include it in your project or use NuGet, which is what I like to do, and then we'll go into the binding dash handler js file. Now let's copy fade visible and create a new one called jq button, and let's delete the code inside of the init and the update just so we have an empty handler, and for this handler, we want to hook into how jQuery UI works. Quire simply, all we're going to do on init when it first loads up is we're going to hook into the element, and we're going to call the button method that jQuery UI exposes, and that's going to be all the init's going to need to do. For the update though, we're going to give you a little bit more work. So we're going to grab the value using the value accessor, but after we do this, we're going to want to apply the jQuery button to the element, and we have to spell this correctly. So we apply the button, and we're going to set the option for disabled on this button. So we're saying there's going to be options that you can pass into jQuery Y, and we're going to set the disable property, and we're going to base that upon if somebody sets the enable property in the binding. So if it equals false, we're going to go ahead and set that, and that's all we have to do to set this binding handler. Now let's go apply it, and to do that, we're going to come back to our html and down in the template, instead of using this fade visible template we have, we're actually going to go ahead and use the product details with jq button, and then we're going to go create that template. It doesn't exist yet, and I'm going to copy the details with fade, and you can just do that from the last example, or you can copy it in from the product details one. Instead of calling it with fade, we'll call it with jq button, and that'll be good, and then we're done here. Open him up. We've got our product details with the close button up top, and we want to actually add a couple things. First, we're going to set the ratings to be a drop down list instead of text box, and we're going to add a button to allow somebody to save it. So let's go ahead and replace this span here. Instead of that, we're going to put in a select for a drop down, and that select, we're going to do a data bind, and inside the data bind, we're going to set the options, and we're just going to hard code the values for 1, 2, 3, 4, and 5. We could've bound this up to an array if we'd wanted to, and then we're going to set the binding value to the word rating, which is going to be the property that's going to be in my view model for that particular item, and I've got a style that I'm going to apply to as well just to make it look a little bit nicer using CSS, and then down at the bottom below the description, we're going to add a button in here. So I'm going to add a button control, and in that button, we're going to set the data dash bind up, and here's where we're going to apply our new binding handler. So we're going to say jQuery button, jq button, and we're going to pass in whether or not we want to enable this, and we're going to enable it based upon a property, and then outside of that, we're also going to bind in what do we want to do when we actually click that button. So we're going to have to create a save method, and we're going to have to create a state has changed and review model. So let's go do that now in our view model. Here we are on the product object. Let's go ahead, and we'll create a new property, say self state has changed, and we'll set that property to be unobservable (it's just going to be a flag) and then by default, we'll make it false because no state has changed, and then let's create our function for saving. So we're going to say save equals function. We're not going to actually do a whole lot here. We're just going to emulate a save. We can do like an alert box and say there was a new rating of, some kind of new rating value of self-rating because we already have a rating property in our individual product, and then we'll go ahead and tack on the word saved at the end. We'll fool the user into thinking it's saved. Ha, ha, ha. And we've got state has changed at the end. We're going to set that to false. We're done. So after we save it, we want to go ahead and reset this. Now we also want to change the state has changed to true, and this is where we're going to take advantage of the subscriptions that we talked about earlier. Here we're going to say self-rating, subscribe, and we're going to subscribe to a change in the individual rating property. What do we want to do? We can say this the state has changed, and we'll set that to true, and because we're using this, we want to pass in self in this case. So self is the owner, and then this will represent self, which happens to be the individual product. Let's go take a look at the html. Here's our template. We're good to go with the template name. We'll look at the template itself. We added to our template the ratings drop down, and then we added jQuery button. We said the state changed true, and we forgot to add the name of the button in there so we have some text to show. So clicking back over to our example, let's run it, and when we click on it, we can see our button, and it's disabled by default because the state has not changed. When we change the rating to something else, we notice it's changed here, and the button becomes enabled, and we could say new rating of 2 has been saved. And that's an example of how you create a binding handler to hook into jQuery's buttons.
Binding Handler with Behavior: starRating Demo
Let's create a custom binding handler that helps us change the look and behavior of an element, and to do that, we've got our structure for binding handler. We're going to call this one star rating. So what we're going to do is instead of using the drop down list for the ratings, the 1 through 5, we're going to have stars show up. Instead of watching me type all this in, we're going to copy and paste a little bit as we go. So first we're going to go ahead and get the element itself that we're binding to and add a star rating class to it. So each element will get that, and then inside of that element, we're going to go ahead and add a span, 1 through 5 basically, to determine how many ratings there's going to be, and then we're going to set up the mouse handling events for the stars because when we hover over the stars, we want them to change their color. So here for the span, we're going to iterate through each individual one, and on hover we're going to go ahead and set up basically setting on the hover chosen class, and then we're going to have the removal of the class where hover chosen as well, and then when we click on in, we're going to set rating observable value to the new rating. So basically we're just doing a lot of little work in here for styling from here down. That's all styling for the actual stars, and then when we click on the star, we're going to get the rating observable, the observe value accessor, and then we're going to increment the value by 1 every time that we click on this item. So that's going to happen on the first time that we come in, and then when we update it, we're going to have to come into here and type in, let's say, let's call it ratings observable again... rating observable, and we'll get the value accessor, and that rating observable value accessor, we're going to use that and then toggle a class for chosen any time that we want to select a particular item. So here we're going to say, get that span element. We'll set the element here and reiterate through each one of them that's in there, and we're going to call a function using an index, and then for that function, we're going to wrap up the individual item. We'll toggle the class called chosen. So in the update, this is where we're going to handle actually selecting a particular item and choosing the value for that as well. So here we've got ratings observable, and if I use IntelliSense, I won't type it wrong. Rating observable, and that's it. So when we're done, we've got a little more complex behavior that we're handling here with the binding handler. We're actually handling displaying the star rating, and we're going to change the hover effect. We're toggling classes, which you've got to have these classes, and they are in your style CSS, and then when we handle the click handler, we're actually going to update the value right in here. So we're actually feeding back into the view model and changing value. We're not just reading the value. Here we're changing the value when somebody selects it. Now we have a place to actually apply this. So in 6.03 for our example, we come down, and we're going to have a template here called products details with star rating. Now that one doesn't exist yet, so we're going to come down and create the new star rating template, and we're going to do that from the jQuery button one, and you can type this in from scratch or you can just copy one of the other ones and start and use that. We'll call this one star rating, and we'll go into the star rating, and now we're going to change the span, the selection box down here for the ratings to a span again. So instead of having that, we're going to come in here and type in a span, and this is kind of where it's really neat. All I have to do is type in span and then set the binding up for this, and I'm going to set the binding to star rating, and then I set the value to whatever the value is. So that's it. There's no extra magic in the template. We're creating our own binding called the star rating, and it's going to be a rating value, which comes out of our view model for each individual product, which will be a value of 1 to 5. So we should now be able to run this guy and see what happens. Let's go back to our index, and we'll click on the star rating control, and when I hover over it, the class is changing. This is where the behavior is actually going in and changing the value of the class, toggling it on and off, and when I click a different rating, you'll notice it's 5 over on the left hand side over here, and I click on the rating to 3. The save button becomes enabled, and it's still bound to 3 over there, and I can click save, and we see that the value is 3. So it's pretty easy to set these different binding handlers up. We see now that you can do it 3 different ways. We've seen a fade operation that we can do with using some jQuery functions, we've seen that we can hook into the jQuery UI or other elements can be done this way, and we've also seen how you can create your own control encapsulaters basically wrappers around controls using something like a star rating.
Unobtrusive JavaScript
Knockout allows you to create your bindings declaratively in the html itself, but what if you want to use unobtrusive JavaScript and actually move those bindings out of the html into JavaScript or using jQuery? Well you can do that, too. For example, you can create your event handlers inside of the bindings such as right here in the example where we have a close icon div class. We have a data mine click is going to call the removed product back in the view model, and here's our view model function. But what you could do is instead of using that html, you could simply have a div class called close icon. You still have your view model, and then inside of jQuery you could actually hook in the click event, and then call the view model's function. So you still have a view model, and you still have review. You're just moving the handler over from inside of the binding itself declaratively over to jQuery. Now by doing that you want to probably want to take advantage of some of the helper functions that Knockout offers. One of them is KO.Data4. Another one's KO.Context4, and what Data4 does for you is it allows you to figure out what is the data for the element that I've just operated on? So in this case here, we're going to click handler using jQuery, how do we know what data I was bound to? Well, that's where Knockout says give me the element of the dom that you were using, and I'll tell you what data was applying to that. So that way we can call the view model remove product function. We can pass in the actual data for it. Another example of using unobtrusive JavaScript is mapping your bindings themselves. So instead of having a bind element in your html where the value is set up to grand total, you'd actually move those out of your html and pull them into jQuery or to JavaScript. So it's just another way to go about doing that, and there's no real special secret sauce to doing this. It's just another option that you can use to actually abstract a way you structure for your presentation. I personally don't mind having all my data money elements inside of my html, but sometimes I do like to have my handlers pulled out into JavaScript or jQuery if the functions get really complex and involved. So let's take a look of an example of how we can move our events out of our bindings, declaratively move it over to jQuery.
Unobtrusive JavaScript: Demo
In this demo, in 6-04, we're going to take a look at how we can move some of our data binding declarations out of the html and move it over to jQuery. So here's the example running, and it works fine. We show our template here, and when I click on the x, the guy disappears with a fade out, and everything reassembles. But let's take a look at how this works, and let's rearrange some of the declarative data binding. So the template that it's using on this page is actually product details medium template, which you have in your starter example, and we can see the close icon at the top Now you'll see we've got the data binding attribute right inside the close binding. That's calling the remove product method. What we could do is we could get rid of that data bind attribute entirely and just go use selectors of jQuery to figure out where the close icon is. So in our html, that's all we need to do. Now we've moved that stuff out, so we no longer have the obtrusive JavaScript, and then over in our view model at the bottom, we set up a selector here. Just to make it easy I've created the selector for us already. So for the selector itself, we're going to use the syntax for jQuery to go ahead and add event handling in, and we'll use the on method that's in jQuery, and that's the new technique. There used to be a live as well, which works in the previous version of jQuery, and there's also delegate. But let's take a look at how on works because that's the newer syntax. So we can say on click, and we can further narrow it down the item we want to select on, and we'll choose the close should be coming up. There it is in IntelliSense, and then the function we want to perform to handle that is right here. So now we just type in our code for our function, and we just want to go into the view model and with IntelliSense we can find we want to call remove product. So Data4 will operate on this, and I've got some extra parens in there, and it basically says go find this for the element, find the data for it, and then that's going to be the product, and we're going to call it remove product, and if we tie it not remove product, we can see him over here, and then basically he's saying products removed, whatever's passed in. Now that's the on syntax if we want to use that. We can also take a look at the delegate syntax for jQuery, which is pretty similar to the on. So the on syntax works in the newer versions of jQuery, but you could also use delegate if you want to work in the older versions and the new versions of jQuery, and here we've got the item selector. Instead of saying on, we say delegate, and then we use the, we actually flip flop these guys. So it's not click there. It's the element that you want to operate on goes here, and then you put the function that you want to have happen to, and then if you want to pass any data in, that comes in here, and then we can actually call into our remove product. I'm going to comment this one out though because we don't want to hook two of these event handlers up to try to remove it twice. So if I run this code now, let's refresh the page. We have the page there, and we should be able to click on x, and it fades away, and it's good to go, and now just to reiterate, we don't have any handling up until inside of our html. It's all actually happening in the jQuery. Let's demonstrate how the Data4 and the Context4 actually differentiate from each other. So let's create another handler here, and we'll do it for click again using the on syntax, and we'll create a function, and then inside of here, let's just do some things like we'll have this actually be right on the item itself. So we're not clicking on the close button. We're just clicking on the item, and let's use the Data4, and we'll get that variable, and we'll just store it into a selected product variable, and then we'll create a selected context variable, and this time we'll use the Context4 function, and we'll get that, and then we can also go ahead and just do something like get my view model, and we could say selected context, and we can do root. So we can use that operation as well that we saw on the previous module, and then for grins we'll use an alert here, and we'll say let's select the selective product, and it's got a property, I believe, called short description. I hope I'm right on that. And we'll display it. So we'll set a break point in the browser and see how this works for us. First we'll refresh. When we click on this time, we should get an alert on the actual item, tailor 314. (Inaudible) here tailor 914. Let's go into the browser's debugger, which we can do through F12, and let's set a break point on the script. So we'll go over to the script itself, hop into my view model, go to the bottom of the page, and let's set a break point right down there, and let's click. Now we're on the break point, and we'll highlight over. Now after I run this guy, I'm hitting F10, the selective product shows up. There's my product, and you see category and description. We're all good to go. That's using the Data4. The selected context over here is actually going to show me the data, the parent, the parents, and root. So if I want to get to something outside of the current data that's selected, I can use the Context4 to get to the context. For example, the star, the dollar sign root is actually going to resolve to the view model itself . So it's a way I can get back to the view model, and then here we're just displaying the short description. So I can let it run, and things are still good to go. But it's really handy to be able to show how you can jump out of using declarative binding and use the jQuery bindings instead, using the functions like Data4 and Context4, and this is one way you can use unobtrusive JavaScript by pulling your bindings out of the data bind tag and moving it over to jQuery, which is really helpful if you've got really complex functions. So you don't want to put all that functionality right inside of your html.
Loading and Saving Data
Chances are if you're building web applications, you're going to have to run into loading and saving data using AJAX, and with Knockout, that's no different. So we're going to take a look at how you can load in from, let's say, an MVC controller or an AZMX file or some other kind of restful service where you get your JSON from and then save your data back using gets and posts. We're going to use AJAX to push these up and down the chain so we can get in and out of Knockout and, of course, into our bindings. So we're going to add a controller, add some models in the next demo, and we're also going to abstract out some of our data calls to some AJAX services and also to some customized services for our apps. We'll show how we can segregate the app and really separate out where our Knockout code begins and ends for our view models and then also our data services, and knockout has some built in functions that'll help us along the way so we can actually get our data from our models back into JSON form.
Ajax, Service Abstraction, and jQuery Dialogs: Demo
So let's take a look at how we can load and save data with Knockout Let's take a look at how we can load and save data using Knockout with AJAX. Now in this example right here in the starter for 6-05, we're loading mock data on the left hand side, and as we click these items through, they're actually getting loaded over to a shopping cart. When we click place order, the idea is that we want to be able to click this button and then it sends it back to our AJAX service on some server somewhere, and then it'll do some processing. Right now the two problems we have are the data on the left is actually coming from client side mock data, so we want to change that out for an AJAX call, and then the place order button is wired up to nothing. So let's go take a look at how we can do this. First we know that we have to go into our view model so we can wire up the load call. So let's go into the view model 4, load saving data and if we find the load method, we can see it right here. It's just loading up some sample data. We don't want to do that. We want to wire into an AJAX call. So let's change this up a little bit. First we want to accept the JSON coming in here, and we're going to make this the call back function because we're going to call this from somewhere else JSON, and now we've got the callback in there, we'll create the load products call that's going to kick everything off, and here's a function, and in this guy, we're going to wire up a service that we have that I created, and this is all inside of your starter files in the before folder. So we've got shopping data service, and we're using IntelliSense for get sale items, my dot view model, load product callback, and what this is doing is it's saying go off and use this object, which we'll take a look at in a moment, and it's going to make an AJAX call to get the products, and then it's going to call the load products callback, which is up here, past the JSON, and then it's going to iterate through and load on the screen. But first we've got to make sure that load products is exposed in our view model. So we'll go ahead and call load products there, and we also want to expose the callback. So let's do that and fill that with IntelliSense, and let's go take a look at how this guy's going to work. So in the shopping data service object, we've got get sale items, which is going to use AJAX to call out to get sale items, and then it's going to fire off to get JSON, and this guy here is just a helper I created to wrap up some of the AJAX calls to a get, and here's another helper to do a post for us. So backing back out of there, the data service is just a nice way to abstract out your calls so you don't have a lot of AJAX calls inside of your view model. It's just a nice separation pattern using SOLID. So if we run this guy, it should work fine for us, but one caveat is because we've using MVC in this project, we're hosting our own server side service to get our JSON data, and that's why we have our product controller. We need to actually crank this up as a product, not just view in browser. So let's do control F5, and that loads the MVC project server site for us. Now we want to come back and actually load up our html. We'll just view it in a browser, and now that server site service is available. So if we take a look through F12, functionality in Chrome, we could see these guys over here, but let's refresh the page, and we'll go to the networking tab, refresh the page, and we can see down here there should be a call somewhere up here. There it was "get sale items" right there, and there's the sale items going off to the server for us, and there's the header doing a get, and that's the actual call out to the (inaudible) service. So now we see we've wired up the AJAX call to do the get. We still need to do the place order. So let's go do that back in our view model. So we've got load products. Now we want to create place order, and that'll be a function, and it's going to call a callback function, too. So let's create the stub for that. That's going to place order, callback. Again we're doing this asynchronously, and then, I forgot to put the function call in there. It's going to equal to a function. Indent those guys, and then we're going to get back some data from the server. So our place order function, we're going to have to make the call out to our service. We could call back into our my shopping data service if you want to. So let's call my shopping data service, and then we'll call his function, which is place order, and then in that guy we're going to call out to the server, and we're going to pass it the shopping cart. So we have to pass the shopping cart variable (use some IntelliSense here) and then we're going to tell it where do you what do you want to do when you come back? I want you to call the callback function called place order callback. So that's going to call out to that service, place the order. It's going to do a post sending my shopping cart JSON data, and when it comes back, I'm going to take advantage of a jQuery UI dialogue wrapper that I created with the help of Ryan E. Meyer (assumed spelling). Thank you very much, Ryan, who basically helped me create a custom binding handler for the dialogue, and this is called dialogue options, and you can see that binding handler in your binding handlers file. We're going to tell it, all right, we want this dialogue to have place order on top of it, and the dialogue's going to have some text inside of it, and we're going to put whatever the return message is from the server. We're getting JSON back, and it's going to have some message property, and then when we're done, we're going to tell it go ahead and open that guy up. Now on top of this, we want to expose these as public properties of our public members of our revealing module pattern. So let's go ahead and do that real quick, and we need to expose the callback, and he's good to go there. So let's take a look at how the dialogues options works quickly. This guy's defined up here as a new dialogue options, which is just some data that we've created, and we can see that right up here. It's got an open property, title text, and then an accept and cancel button. Now if you want to use this binding handler, what I would recommend you do is, for your convenience, go into the binding handlers file, and you can try typing this yourself or you can go into the code before folder from module 6. You'll see a binding handlers text file. If we open that up, we can just copy the contents of that file and overwrite the entire binding handlers JS, and there's actually a couple of things in there like the star ratings we looked at, and then here is the jq dialogue, which is the binding handler that's going to be using for the jQuery UI binding. So we need to wire that guy up, and we also need to wire in the place order. So when we go to the button for place order, we can see we're using jQuery button. So this is where we want to use the click handler here, and we want to do place order, and that'll automatically wire in the view model's place order function for us, and then at the bottom, we're going to have a div here, and we're using a custom binding, the one we just looked at, the jQuery UI dialogue. We're going to pass in the dialogue options. This is a property in my view model, which has the name, the title, and the message for my dialogue, and then inside of that, we're going to stick the text from dialogue options. So when we run this guy, and the server side should be running for us, so we should be able to load him up, hitting the network. We could add a couple of guys to our cart. Let's do that, and here's our order total. We place the order. Well, before we place the order, let's open up the network and watch what happens. We place the order we should get save three items for a total of $189. We can see that's the price over here, and we can also see the place order did a post all the way to the server. So you can see how easy it is to create AJAX calls and hook it into your Knockout application, like you would any other application, and then we can hook into jQuery dialogue to do something like a custom binding handler, too. The complete source for this can be found in the after solution for module 6, and you can take a look at all those binding handlers in there, too. There's quite a few of them in there. I would definitely recommend taking a look at some of them such as the jQuery dialogue, the star rating one. There's also another jQuery one for the button that's in here, and then there's a slide visible, which is a bonus one, and fade visible. Many of there are up on the learn.Knockout JS.com site, too.
Change Tracking
When building web applications, especially with Knockout and using view models, you may want to handle situations where you load data in from AJAX, the user enters some data and makes some changes, and then you're automatically notified that there are changes. So you could like enable a save button or allow the person to actually place an order after placing items in their shopping cart. This form of change tracking is pretty easy to implement using Knockout and the view model structure. For example, we could just create a change tracker object on our view model and then have it hanging off as a property on the view model, and then whenever something changes, we could fire off something has changed, and then, of course, whenever you load or you save or you want to re-synch changes up, you can mark the state as clean. Now I've created an object that's pretty simple. I think it's only about 25 lines of code, and it's called a change tracker object that works with Knockout and view models, and I'm going to demonstrate how this works and how simple it is to implement, and the source code for this change tracker is in your sample project, but you can also get the latest version by using NuGet, and there's a package up on there which will give you the latest version of the bits. Well, let's jump into the demo and see how this works.
Change Tracking: Demo
In this example, let's take a look at how we can add in the change tracker and handle change tracking in our app. First we're going to go out to the NuGet packages and we're going to search for the Knockout change tracker, and as we scroll down the list, we can see a couple packages are available. Here's the change tracker, and we can install that really quickly. Once it's installed, we should be able to go down to the scripts folder, and we should see in here, there should be a if I have the right folder, which should be a scripts folder. There should be a scripts folder, Knockout change tracker, and now what this simply does, it allows you to do some change tracking in your application when you create your view model. The change tracker here is hanging off the Knockout object, and it exposes a couple of functions publically. Something has changed, which will return back a true or false evaluation based upon the last clean state of the view model, and then also a mark current state as clean, which you can use to reset your view model state. So it's just going to track your state of your view model, and you can pass in a hash function if you wanted your own custom one, or, by default, it's just basically going to take the JSON of the object, and compare it against its current state. But let's see how we can take advantage of using this. We'll go to our html file first before we forget, or before I forget, and let's add in that file. We'll come over here, and we'll just simply drag it up, and something I like to do after I drag them is just be consistent with my paths. So now we have the change tracker being used in the html file. Let's make that go away. Now in the html file, we want to enable the place order button at the bottom of the screen based upon if changes have occurred. So we're gong to change the shopping cart length greater than zero to another expression. Before we do that, let's go back into our script file for this view model, which is called 6-06 change tracker, and in here let's add in a few places the change tracker for the view model, and then down here off the shopping cart, this is in the view model, we're going to add our tracker object, and we can call this whatever we want. It's basically going to be a property on top of a view model that allows us to handle change tracking. So here we're just going to create a new instance of change tracker, and that's actually going to be a new instance in this case, and this change tracker is going to accept two variables if you remember. The first variable is the view model that we can track, and we don't actually want to track the entire view model in this particular case. We're just going to track the state of the shopping cart because we only want to know if anything changed in the shopping cart, but we could do the entire view model if we wanted to. And then the second option is to pass a hash function, which we're going to just use the 2 JSON method, which is what it's using right now. So that's going to handle creating the change tracker for us. Now we actually want to set the current state to be clean. Let's go down to the load products callback, and in load products callback, as soon as we make that call, we can go ahead and type in the name of our tracker, and we call this guy tracker, and on him we can mark the current state as clean, and that's going to basically set it to its default state, and then also we want to do this in the place order callback. So when we come back from placing an order, we're done placing the order, the shopping cart should be updated, we're going to mark the state as clean for that as well. So that's going to mark our state clean for both of those, and then we also, (inaudible) module pattern, we want to come into here and expose our tracker variable so we can use that in our code. Now that we've got that set up in the JavaScript, we can come back over to here to the button. Instead of enabling that one, the shopping cart has items in it. That's not going to work after we place an order properly. What we want to do is rewrite this code so it's actually using the tracker, and on that tracker, we can check the something has changed. So if something has changed, it's set to true. So now we should be able to save this and view it in the browser. Let's take a look, and when that comes up here, we see the place order button is set to disabled. As soon as I add an item to the shopping cart, both those guys in here, now I press place order, it should disable the button afterwards. So we're going to accept that, and now notice it's disabled. If I remove an item from the shopping cart because the state has now changed, it's now a dirty state. Therefore, I have to place the order again, and I can wipe it out. Now something cool about this is let's add a few items, and as I actually add those items, let's place the order. Now notice I'm in that clean state. If I change the quantity on here, too, it's not just tracking the observables, anything inside of there. As soon as I change the quantity from 1 to 12, notice the place order button became enabled. So just like we had with the external template plugin that we saw in the previous module and we have here with the change tracking, which we'll get through NuGet, you can extend Knockout in a variety of ways to enhance the features that it has. There's also a mapper function, too, that Ryan E Meyer has written. So you can really extend these tools pretty much any way you want to, and this is just one other example of how you can use Knockout.
Knockout Mapper
There's another nice plugin that I want to point out. It's up on the NuGet site, so you can pull it down to the visuals studio or off the website itself, and it's called the Knockout Mapper, and what this does, it allows you to map your objects from JSON right into your JavaScript objects, and it actually will wrap those objects up using the observable functions. So you might be getting some JSON from a web service, and that JSON comes back as normal data, and then you want to wrap it up inside of objects that have the KO.observable or KO.observableArray. Well, if you use the Knockout JS Mapper, it'll actually map all those for you, and then you can actually unmap it when you want to send it back over the AJAX wire, and basically the way this works is you call the KO.mapping from JS with your result, and you can map the result, which is just your pure JSON from the web service, map that into your local model, and then to go back on a save method, you might use the mapping to JSON method and pass the model in, which will then unwrap all the observables for you and put it back into its normal JSON state, and this is one of the nicer plugins for Knockout that exist out there.
Summary and Tips
In this module, we took a close look at custom binding handlers and how you can create your own bindings to pretty much do whatever you want to do. So you don't have to rely just on the built in bindings in Knockout. You can really extend them to do things like integrate with jQuery UI or other kind of UI structures, or you can create them to do kind of behavioral things, like we showed with the star ratings, or you can also just create jQuery type animations like we did with the fade in, fade out or fade visible. We also explored unobtrusive JavaScript and how Knockout supports that structure so you don't have to put all of your data bind syntax inside the html. You can actually pull some of them back out, both the binding structures for hooking into events, such as jQuery events using the on or the delegate syntax, or you can also take in, pull your data bind attributes out, too, if you just want to set your attributes through using something like jQuery or just straight up JavaScript. And then finally we kind of wrapped up with dealing with how do we save and load data, hooking AJAX into our application, how do we do mapping with our mapper, and then also change tracking. So the theme of this module is how you can customize a lot of the features of Knockout and really go beyond what comes out of the box using things like custom binding handlers or hooking into AJAX, hooking into jQuery Y, adding plugins like the change tracking or the mapping. So Knockout just really provides the basis for building web applications and then you can really extend where you want to.
Course author
John Papa
John Papa is a Principal Developer Advocate with Microsoft and an alumnus of the Google Developer Expert, Microsoft Regional Director, and MVP programs.
Course info
LevelIntermediate
Rating
(880)
My rating
Duration4h 50m
Released14 Feb 2012
Share course