What do you want to learn?
Skip to main content
by John Papa
Start CourseBookmarkAdd to Channel
Table of contents
MVVM with Knockout
MVVM with Knockout: Demo
Using Knockout in Visual Studio
Using Knockout in Visual Studio: Demo
Begin Coding with Knockout
Begin Coding with Knockout: Demo
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 )
Bindings and Observables
( 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
Push and Pull Data without Data Binding: 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: 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
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 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
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 )
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
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.
Spaghetti to Ravioli
Spaghetti to Ravioli: Demo
Object Literals and 'this'
Object Literals and 'this': Demo
The Module Pattern for ViewModels
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 Revealing Module Pattern for ViewModels: Demo
Summary and Tips
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.
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
External Templates: Demo
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
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
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.
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.
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
Summary and Tips
John Papa is a Principal Developer Advocate with Microsoft and an alumnus of the Google Developer Expert, Microsoft Regional Director, and MVP programs.
Released14 Feb 2012