The view-model
The view-model is a pure code representation of the data and operations on a UI. It isn't the UI itself. It doesn't have any concept of buttons or display styles. It's not the persisted data model either. It holds the unsaved data the user is working with. View-models are pure JavaScript objects that have no knowledge of HTML. Keeping the view-model abstract in this way lets it stay simple, so you can manage more sophisticated behaviors without getting lost.
To create a view-model, we just need to define a simple JavaScript object:
var vm = {};
Then to activate Knockout, we will call the following line:
ko.applyBindings(vm);
The first parameter says which view-model object we want to use with the view. Optionally, we can pass a second parameter to define which part of the document we want to search for data-bind
attributes.
ko.applyBindings(vm, document.getElementById('elementID'));
This restricts the activation to the element with elementID
and its descendants, which is useful if we want to have multiple view-models and associate each with a different region of the page.
The view
A view is a visible, interactive UI representing the state of the view-model. It displays information from the view-model, sends commands to the view-model (for example, when the user clicks on buttons), and updates whenever the state of the view-model changes. In our projects, views are represented by the HTML markups.
To define our first view, we are going to build an HTML to display a product. Add this new content to the container:
<div class="container-fluid"> <div class="row"> <div class="col-md-12"> <!-- our app goes here → <h1>Product</h1> <div> <strong>ID:</strong> <span data-bind="text:product.id"></span><br/> <strong>Name:</strong> <span data-bind="text:product.name"></span><br/> <strong>Price:</strong> <span data-bind="text:product.price"></span><br/> <strong>Stock:</strong> <span data-bind="text:product.stock"></span> </div> </div> </div> </div>
Look at the data-bind
attribute. This is called declarative binding. This attribute isn't native to HTML, though it is perfectly correct. But since the browser doesn't know what it means, you need to activate Knockout (the ko.applyBindings
method) to make it take effect.
To display data from a product, we need to have a product defined inside our view-model:
var vm = {
product: {
id:1,
name:'T-Shirt',
price:10,
stock: 20
}
};
ko.applyBindings(vm);//This how knockout is activated
Add the view-model to the end of the script tags:
<script type="text/javascript" src="js/viewmodel.js"></script>
Tip
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
This will be the result of our app:
The model
This data represents objects and operations in your business domain (for example, products) and is independent of any UI. When using Knockout, you will usually make AJAX calls to some server-side code to read and write this stored model data.
Models and view-models should be separated from each other. In order to define our product model, we are going to follow some steps:
- Create a folder inside our
js
folder. - Name it
models
. - Inside the
models
folder, create a JavaScript file calledproduct.js
.
The code of the product.js
file is as follows:
var Product = function (id,name,price,stock) { "use strict"; var _id = id, _name = name, _price = price, _stock = stock ; return { id:_id, name:_name, price:_price, stock:_stock }; };
This function creates a simple JavaScript object that contains the interface of the product. Defining the object using this pattern, called the revealing module pattern, allows us to clearly separate public elements from private elements.
To learn more about the revealing module pattern, follow the link https://carldanley.com/js-revealing-module-pattern/.
Link this file with your index.html
file and set it at the bottom of all the script tags.
<script type="text/javascript" src="js/models/product.js"> </script>
Now we can use the product model to define the product in the view-model:
var vm = { product: Product(1,'T-Shirt',10,20); }; ko.applyBindings(vm);
If we run the code again, we will see the same result, but our code is more readable now. View-models are used to store and handle a lot of information, because of this view-models are commonly treated as modules and the revealing module pattern is applied on them. This pattern allows us in a clear manner to expose the API (public elements) of the view-model and hide private elements.
var vm = (function(){ var product = Product(1,'T-Shirt', 10, 20); return { product: product }; })();
Using this pattern when our view-model begins to grow helps us to clearly see which elements belong to the public part of the object and which ones are private.