Templates in Knockout.js provide a powerful way to organize and reuse UI components, making your code more modular and maintainable. Here’s a guide to get you started with templates in Knockout.js.
Step 1: Setting Up Your Project
Ensure you have Knockout.js included in your project. You can include it via a CDN:
<!doctype html>
<html lang="en">
<head>
<!-- Meta tags for character set and viewport configuration -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Title of the webpage -->
<title>Bootstrap demo</title>
<!-- Link to Bootstrap CSS for styling -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<!-- Link to Knockout.js library for MVVM pattern support -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.min.js"
integrity="sha512-vs7+jbztHoMto5Yd/yinM4/y2DOkPLt0fATcN+j+G4ANY2z4faIzZIOMkpBmWdcxt+596FemCh9M18NUJTZwvw=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>
<body class="container">
</body>
</html>
Step 2: Creating Templates
Templates in Knockout.js can be defined in script tags or directly in HTML. Here's an example of both:
In Script Tags:
<script type="text/html" id="person-template">
<div>
<h3 data-bind="text: name"></h3>
<p>Age: <span data-bind="text: age"></span></p>
</div>
</script>
Direct in HTML
<div id="person-template" style="display: none;">
<div>
<h3 data-bind="text: name"></h3>
<p>Age: <span data-bind="text: age"></span></p>
</div>
</div>
Step 3: Binding Templates to View Models
To use a template, bind it to a part of your view model using the template
binding.
View Model:
function Person(name, age) {
this.name = name;
this.age = age;
}
function AppViewModel() {
this.people = ko.observableArray([
new Person('John Doe', 25),
new Person('Jane Smith', 30)
]);
}
ko.applyBindings(new AppViewModel());
Applying the template
<div data-bind="foreach: people">
<div data-bind="template: { name: 'person-template', data: $data }"></div>
</div>
Step 4: Using Named Templates
You can also create named templates to be reused in multiple places.
Define Named Template:
<script type="text/html" id="person-template">
<div>
<h3 data-bind="text: name"></h3>
<p>Age: <span data-bind="text: age"></span></p>
</div>
</script>
Use Named Template in Multiple Places:
<div data-bind="template: { name: 'person-template', data: { name: 'Alice', age: 28 } }"></div>
<div data-bind="template: { name: 'person-template', data: { name: 'Bob', age: 35 } }"></div>
Step 5: Organizing Templates in External Files
For larger projects, it’s often better to organize templates in separate HTML files and load them as needed.
External Template File (templates.html
):
<div type="text/html" id="person-template">
<div>
<h3 data-bind="text: name"></h3>
<p>Age: <span data-bind="text: age"></span></p>
</div>
</div>
Load and Use the External Template:
Use an AJAX request to load the external template file and append it to the DOM.
$(function() {
// Load external template file
$.get('templates.html', function(templates) {
$('body').append(templates);
// Apply bindings after templates are loaded
function Person(name, age) {
this.name = name;
this.age = age;
}
function AppViewModel() {
this.people = ko.observableArray([
new Person('John Doe', 25),
new Person('Jane Smith', 30)
]);
}
ko.applyBindings(new AppViewModel());
});
});
Step 6: Advanced Template Features
Knockout.js offers additional features like template options (if
,
foreach
, as
) and custom bindings to further enhance your template management.
Using if
and foreach
:
<div data-bind="if: selectedPerson">
<div data-bind="template: { name: 'person-template', data: selectedPerson }"></div>
</div>
<div data-bind="foreach: people">
<div data-bind="template: { name: 'person-template', data: $data }"></div>
</div>
View Model with Conditional and Looping:
// Apply bindings after templates are loaded
class Person {
constructor(name, age, is_selected = false){
this.name = ko.observable(name);
this.age = ko.observable(age);
this.is_selected = ko.observable(is_selected)
}
}
$(function() {
// Load external template file
$.get('templates.html', function(templates) {
$('body').append(templates);
function AppViewModel() {
var self = this;
self.people = ko.observableArray([
new Person('John Doe', 25, true),
new Person('Jane Smith', 30, false)
]);
self.selectedPerson = ko.observable(self.people()[0]);
}
ko.applyBindings(new AppViewModel());
});
});
Now combine the whole code
index.html
<!doctype html>
<html lang="en">
<head>
<!-- Meta tags for character set and viewport configuration -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Title of the webpage -->
<title>Bootstrap demo</title>
<!-- Link to Bootstrap CSS for styling -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<!-- Link to Knockout.js library for MVVM pattern support -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.min.js"
integrity="sha512-vs7+jbztHoMto5Yd/yinM4/y2DOkPLt0fATcN+j+G4ANY2z4faIzZIOMkpBmWdcxt+596FemCh9M18NUJTZwvw=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<!-- Container class for Bootstrap styling -->
<body class="container">
<p class="fw-bold ">Selected Person</p>
<div data-bind="if: selectedPerson">
<div data-bind="template: { name: 'person-template', data: selectedPerson }"></div>
</div>
<p class="fw-bold">All Person</p>
<div data-bind="foreach: people">
<div data-bind="template: { name: 'person-template', data: $data }"></div>
</div>
</body>
<script src="app.js"></script>
</html>
app.js
// Apply bindings after templates are loaded
class Person {
constructor(name, age, is_selected = false){
this.name = ko.observable(name);
this.age = ko.observable(age);
this.is_selected = ko.observable(is_selected)
}
}
$(function() {
// Load external template file
$.get('templates.html', function(templates) {
$('body').append(templates);
function AppViewModel() {
var self = this;
self.people = ko.observableArray([
new Person('John Doe', 25, true),
new Person('Jane Smith', 30, false)
]);
self.selectedPerson = ko.observable(self.people()[0]);
}
ko.applyBindings(new AppViewModel());
});
});
templates.html
<div id="person-template">
<div data-bind="attr: { class : is_selected() ? 'border-bottom mb-3' : ''}">
<div>
<h3 data-bind="text: name"></h3>
<p> <span data-bind="text: age"></span></p>
</div>
</div>
Read more
Client-Side vs. Server-Side Validation: When to Use Each in Knockout.js
Integrating KnockoutJS with other technologies like ASP.NET, Node.js, or RESTful APIs?
Leave Comment