1

I have just started learning KnockoutJS. This is code for folder navigation of webmail client.In the view code, a comparision is made whether the reference variable $data and $root.chosenFolderId() point to the same memory location. But I don't understand what will be the initial value of $root.chosenFolderId()?

Reference

View:

<!-- Folders -->
<ul class="folders" data-bind="foreach: folders">
<li data-bind="text: $data, css : {selected: $data == $root.chosenFolderId()}, click: $root.goToFolder"></li>
</ul>

View Model:

function WebmailViewModel() {
    // Data
    var self = this;
    self.folders = ['Inbox', 'Archive', 'Sent', 'Spam'];

    self.chosenFolderId = ko.observable();

    //Operations
    self.goToFolder = function(folder){
        self.chosenFolderId(folder);
    };
};

ko.applyBindings(new WebmailViewModel());
Ashley
  • 441
  • 2
  • 8
  • 27
  • Well, what happened when you tried it? – nnnnnn Oct 09 '16 at 07:21
  • 1
    Initial, no folder is selected but when I click on a folder, it gets selected. Its working but I don't understand how !How does $data == $root.chosenFolderId() matching works ? – Ashley Oct 09 '16 at 07:24
  • `$data` contains the current item in the iteration on `folders` ("Inbox" for the first iteration) and `$root.chosenFolderId()` contains a `string` that is one of the items in `folders`. There is no "memory location" comparison involved, only simple `string` comparison. – haim770 Oct 09 '16 at 07:29
  • How will `chosenFolderId` variable know that it has to pick up one of the value from `folders` array ? – Ashley Oct 09 '16 at 07:57
  • I'm going through this same tutorial, and I have the same question. The answer below doesn't really help me understand what is going on, though. –  May 12 '23 at 18:32

1 Answers1

1

You're 90% there. As you stated, the foreach will iterate over the folders array and $data will be the current item in the array.

Picking up the value for chosenFolderId

The click binding which calls goToFolder will pass the item it was bound to as an argument, so the chosenFolderId value will be set to the folder item corresponding to the clicked <li> element.

For example: clicking on the 'Archive' element will fire the click event for the item bound to folders[1] thereby calling goToFolder with the folders[1] value.

Initial value

The initial value of $root.chosenFolderId() will be undefined since you declared it with no argument. On initial view no folders appear selected, if you had:

self.folders = ['Inbox', 'Archive', 'Sent', 'Spam'];
self.chosenFolderId = ko.observable(self.folders[0]);

then the 'Inbox' would be initially selected.

Memory location

You asked if $data and $root.chosenFolderId() point to the same memory location. That's mostly correct - if your folders were an array of objects then they would contain the same reference (for the selected item). Technically strings are also references in JS (see explanation https://stackoverflow.com/a/51193/625200) but its simpler to think of primitives (strings, numbers, booleans) in JS as values and not references.

Community
  • 1
  • 1
johnhunter
  • 1,826
  • 15
  • 19
  • Thanks for the well explained answer! So first the click binding will be applied and then the css binding would work ? Assuming the `foreach` runs infinitely here. – Ashley Oct 09 '16 at 17:30
  • I'm going through this same tutorial, and I have the same question. The answer here doesn't really help me understand what is going on, though. Is `chosenFolderId` a variable? It is never declared. I searched online to find out what it was, and this is the only place I saw it mentioned. How does Javascript know what to do with it? I'm confused. –  May 12 '23 at 18:35