Follow @endyourif rss Facebook LinkedIn

Knockout: `this` context with ko computed observables and subscribe Knockout: `this` context with ko computed observables and subscribe

Published on May 29, 2017

In JavaScript, the `this` variable inside a function (like a computed observable or a Knockout subscribe) function can be an extremely useful variable to access related properties to your observable.  Learning the following behavior has opened many doors for me when leveraging the Knockout.js framework. This Knockout js tutorial will demonstrate through an example using a computed observable inside my ViewModel.



Creating a basic Knockout ViewModel



Let's begin with a simple ViewModel example:


<!DOCTYPE html>

<html>

<head>

<title>Data Binding with KnockoutJS</title>

</head>

<body>

<h1>Hello <span data-bind="text: fullName"></span></h1>

 

<script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js'></script>

<script>

var viewModel = function() {

 

this.person = {

firstName: 'End',

middleName: 'Your',

lastName: 'If'

};

 

this.fullName = ko.computed(function() {

return this.person.firstName

+ ' ' + this.person.middleName

+ ' ' + this.person.lastName;

});

 

};

 

ko.applyBindings(viewModel);

</script>

</body>

</html>


As you can see inside my ViewModel, inside my fullName computed observable, this is referencing my outer ViewModel; sometimes useful, sometimes not.  In this case it's not quite as useful because I need to reference the person object 3 separate times.

Using this with a computed observable



In this next example I am going to override the default this by passing the person object and defining it as the new this for my computed observable.  This also allows me to remove the 3 references to the person object and just use this as it has been changed to the person object.


<!DOCTYPE html>

<html>

<head>

<title>Data Binding with KnockoutJS</title>

</head>

<body>

<h1>Hello <span data-bind="text: fullName"></span></h1>

 

<script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js'></script>

<script>

var viewModel = function() {

 

this.person = {

firstName: 'End',

middleName: 'Your',

lastName: 'If'

};

 

this.fullName = ko.computed(function() {

return this.firstName

+ ' ' + this.middleName

+ ' ' + this.lastName;

}, this.person);

 

};

 

ko.applyBindings(viewModel);

</script>

</body>

</html>


I personally find this is even more useful when inside of an array of objects.  This final example will create a list of people using the similar concept.  Once the array of people is created, the previous h1 tag is wrapped in a Knockout foreach loop to display all fullName's of the people.

When you are setting up your data bindings I have an article about Uncaught ReferenceError: Unable to process binding in the odd scenario that an unclear binding issue has occurred.


<!DOCTYPE html>

<html>

<head>

<title>Data Binding with KnockoutJS</title>

</head>

<body>

<!-- ko foreach: people -->

<h1>Hello <span data-bind="text: fullName"></span></h1>

<!-- /ko -->

 

<script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js'></script>

<script>

var viewModel = function() {

 

this.people = [

{

firstName: 'End',

middleName: 'Your',

lastName: 'If'

},{

firstName: 'End',

middleName: 'Your',

lastName: 'If'

}

];

 

for (var x = 0; x < this.people.length; x++) {

var person = this.people[x];

 

person.fullName = ko.computed(function() {

return this.firstName

+ ' ' + this.middleName

+ ' ' + this.lastName;

}, person);

}

};

 

ko.applyBindings(viewModel);

</script>

</body>

</html>


Hopefully this will help you as much as it did me.

Tags: Knockout js Tutorial | observable | this

My Books
ASP.NET MVC 5 With Bootstrap and Knockout.js
Knockout.js Building Dynamic Client-Side Applications
20 Recipes for Programming MVC 3
20 Recipes for Programming PhoneGap
Rapid Application Development with CakePHP