By
``` When viewed in the browser, the content of the element is replaced with the value in the viewModel variable: ![knockout simple binding](knockout/_static/simple-binding-screenshot.png) We now have simple one-way binding working. Notice that nowhere in the code did we write JavaScript to assign a value to the span's contents. If we want to manipulate the ViewModel, we can take this a step further and add an HTML input textbox, and bind to its value, like so: ```htmlAuthor Name:
``` Reloading the page, we see that this value is indeed bound to the input box: ![knockout input binding](knockout/_static/input-binding-screenshot.png) However, if we change the value in the textbox, the corresponding value in the `` element doesn't change. Why not? The issue is that nothing notified the `` that it needed to be updated. Simply updating the ViewModel isn't by itself sufficient, unless the ViewModel's properties are wrapped in a special type. We need to use **observables** in the ViewModel for any properties that need to have changes automatically updated as they occur. By changing the ViewModel to use `ko.observable("value")` instead of just "value", the ViewModel will update any HTML elements that are bound to its value whenever a change occurs. Note that input boxes don't update their value until they lose focus, so you won't see changes to bound elements as you type. > [!NOTE] > Adding support for live updating after each keypress is simply a matter of adding `valueUpdate: "afterkeydown"` to the `data-bind` attribute's contents. You can also get this behavior by using `data-bind="textInput: authorName"` to get instant updates of values. Our viewModel, after updating it to use ko.observable: ```javascript var viewModel = { authorName: ko.observable('Steve Smith') }; ko.applyBindings(viewModel); ``` Knockout supports a number of different kinds of bindings. So far we've seen how to bind to `text` and to `value`. You can also bind to any given attribute. For instance, to create a hyperlink with an anchor tag, the `src` attribute can be bound to the viewModel. Knockout also supports binding to functions. To demonstrate this, let's update the viewModel to include the author's twitter handle, and display the twitter handle as a link to the author's twitter page. We'll do this in three stages. First, add the HTML to display the hyperlink, which we'll show in parentheses after the author's name: ```html``` Then, add the function to the viewModel, and wire it up to modify the viewModel's state. Notice that to set a new value to the twitterAlias property, we call it as a method and pass in the new value. ```javascript function viewModel() { this.authorName = ko.observable('Steve Smith'); this.twitterAlias = ko.observable('@ardalis'); this.twitterUrl = ko.computed(function() { return "https://twitter.com/" + this.twitterAlias().replace('@',''); }, this); this.capitalizeTwitterAlias = function() { var currentValue = this.twitterAlias(); this.twitterAlias(currentValue.toUpperCase()); } }; ko.applyBindings(viewModel); ``` Running the code and clicking the button modifies the displayed link as expected: ![hyperlink capitalize](knockout/_static/hyperlink-caps-screenshot.png) ## Control flow Knockout includes bindings that can perform conditional and looping operations. Looping operations are especially useful for binding lists of data to UI lists, menus, and grids or tables. The foreach binding will iterate over an array. When used with an observable array, it will automatically update the UI elements when items are added or removed from the array, without re-creating every element in the UI tree. The following example uses a new viewModel which includes an observable array of game results. It is bound to a simple table with two columns using a `foreach` binding on the `` element. Each `
Opponent | Result |
---|---|