I have been struggling to understand why the binding is not working as expected for the ‘(not working binding on click)’ in the HTML section. I have a basic list of Players, and when I click on one of them, the bound name should change at the bottom of the page: 1) The player name bound with vm.selectedPlayerName appears correctly. 2) The player name bound with vm.selectedPlayer.name() only shows up correctly during page load and never updates on the click event, despite the selectedPlayer object changing properly (as seen in the console log). I want to fix issue 2) so that I don't have to redefine properties in the view model. What could be causing this problem?
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.0.min.js"></script>
<script type='text/javascript' src='http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js'></script>
<script>
$(document).ready(function () {
var my = {}; //my namespace
// Player
my.Player = function () {
this.name = ko.observable("");
};
// The ViewModel
my.vm = function () {
var
players = ko.observableArray([]),
selectedPlayer = ko.observable(),
selectedPlayerName = ko.observable(""),
goToDetails = function (aPlayer) {
my.vm.selectedPlayer = aPlayer;
my.vm.selectedPlayerName(my.vm.selectedPlayer.name());
console.log("goToDetails: ", my.vm.selectedPlayerName());
},
loadPlayers = function () {
my.vm.players.push(new my.Player().name("Player1"));
my.vm.players.push(new my.Player().name("Player2"));
my.vm.players.push(new my.Player().name("Player3"));
my.vm.selectedPlayer = my.vm.players()[0];
my.vm.selectedPlayerName(my.vm.selectedPlayer.name());
};
return {
// Data
players: players,
selectedPlayer: selectedPlayer,
selectedPlayerName: selectedPlayerName,
// Other
loadPlayers: loadPlayers,
goToDetails: goToDetails,
};
}();
my.vm.loadPlayers();
ko.applyBindings(my.vm);
});
</script>
<title></title>
</head>
<body>
<table>
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody data-bind="foreach: players">
<tr>
<td data-bind="text: name, click: $root.goToDetails"></td>
</tr>
</tbody>
</table>
<p>
Selected player (working binding on click): <span data-bind='text: $root.selectedPlayerName'></span>
<br />
Selected player (not working binding on click): <span data-bind='text: selectedPlayer.name()'></span>
</p>
</body>