Knockout: `this` context with computed observables and subscribe

Published on May 29, 2017 by Jamie Munro

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.



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.

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.


<!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: KnockoutJS | knockoutjs | this

Related Posts

blog comments powered by Disqus