articles

Home / DeveloperSection / Articles / Getting Started with Templates in Knockout.js: How to Organize and Reuse UI Components

Getting Started with Templates in Knockout.js: How to Organize and Reuse UI Components

Getting Started with Templates in Knockout.js: How to Organize and Reuse UI Components

Ravi Vishwakarma 167 26-Jun-2024

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?

 


Hi, my self Ravi Vishwakarma. I have completed my studies at SPICBB Varanasi. now I completed MCA with 76% form Veer Bahadur Singh Purvanchal University Jaunpur. SWE @ MindStick | Software Engineer | Web Developer | .Net Developer | Web Developer | Backend Engineer | .NET Core Developer

Leave Comment

Comments

Liked By