How can a knockout understand the data-bound object when it only has access to its name?

I am currently working on a project where I have the following code:

<form action='/someServerSideHandler'>
  <p>You have asked for <span data-bind='text: gifts().length'>&nbsp;</span> gift(s)</p>
  <table data-bind='visible: gifts().length > 0'>
    <thead>
      <tr>
        <th>Gift name</th>
        <th>Price</th>
        <th />
      </tr>
    </thead>
    <tbody data-bind='foreach: gifts'>
      <tr>
        <td><input class='required' data-bind='value: name, uniqueName: true' /></td>
        <td><input class='required number' data-bind='value: price, uniqueName: true' /></td>
        <td><a href='#' data-bind='click: $root.removeGift'>Delete</a></td>
      </tr>
    </tbody>
  </table>

  <button data-bind='click: addGift'>Add Gift</button>
  <button data-bind='enable: gifts().length > 0' type='submit'>Submit</button>
</form>

and

var GiftModel = function(gifts) {
var self = this;
self.gifts = ko.observableArray(gifts);

self.addGift = function() {
  self.gifts.push({
    name: "",
    price: ""
  });
};

self.removeGift = function(gift) {
  self.gifts.remove(gift);
};

self.save = function(form) {
  alert("Could now transmit to server: " + ko.utils.stringifyJson(self.gifts));
  // To actually transmit to server as a regular form post, write this: ko.utils.postJson($("form")[0], self.gifts);
};
};

var viewModel = new GiftModel([
    { name: "Tall Hat", price: "39.95"},
    { name: "Long Cloak", price: "120.00"}
]);
ko.applyBindings(viewModel);

// Activate jQuery Validation
$("form").validate({ submitHandler: viewModel.save });

I have been wondering how ko.applyBindings(viewModel); is making the binding by the name of the variable. Is Knockout searching it somehow by name? How does the template know that this is its array/data set? As a .NET developer, the concept of fetching something "by name" is not clear to me. Am I mistaken in thinking that it is fetched by name? I have read the documentation but I still do not understand how Knockout connects the template gifts() with the array named gifts from the model?

By the way, this code snippet is from the main page of Knockout.

Answer №1

What is the process through which ko.applyBindings(viewModel); is creating bindings based on variable names? Is Knockout searching for them by name somehow?

Simplifying a bit, two key differences between Javascript (more so than KO) and .NET that relate to your question:

  • All members (e.g. self.gifts) can be accessed as if self had a string-based indexer to retrieve them (e.g. self['gifts']);
  • Javascript is dynamically typed, allowing self['gifts'] to contain an array, string, observable, etc. at runtime.

Therefore, Knockout can take your string "gifts", use it to access the variable self["gifts"], and determine its type at runtime to select the appropriate code path accordingly.

Regarding your other query:

How does the template recognize that this is its array/data set?

Knockout is open source (although not necessarily beginner-friendly with JS), and upon examining it, you'll discover that foreach assumes it receives an array.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Manipulating array elements in MongoDB using sort values in Mongoose JS

I am currently developing a quiz application where teams compete in rounds of 12 questions. After each round, I want to award points to the participating teams based on their performance. The team with the most correct answers will receive 3 points, the se ...

Dynatree fails to consider the select feature while utilizing ajax requests

Currently, I am utilizing the dynatree plugin to exhibit a checkbox tree in multi-select mode (mode 3). Upon initializing the tree using ajax (without lazy loading), it appears that certain nodes that were initially loaded as selected are forgotten. When ...

Error encountered in attempting to create an embed using discord.js v14.7.1: TypeError - The value being extended, either undefined or null, is not a valid

The specific problem arises when defining the module export for the HelpCommand class: **module.exports = class HelpCommand extends Command {** The content of the help.js file, without URLs, is as follows: const fs = require('fs'); const { Comma ...

A guide on accessing every element within a "div" tag that begins with a specified text

In my HTML document, there is a div element present. I am looking to retrieve all elements within this specific div that have id attributes beginning with a certain string (e.g. "q17_"). Is it possible to accomplish this task using JavaScript? If necess ...

Why is it that the HttpClient constructor in Angular doesn't require parameters when instantiated through the constructor of another class, but does when instantiated via the 'new' keyword?

I am trying to create a static method for instantiating an object of a class, but I have encountered a problem. import { HttpClient } from '@angular/common/http'; export MyClass { // Case 1 public static init(): MyClass { return this(new ...

How can I stop Jquery Mobile from processing the URL hash?

Currently implementing Jquery Mobile in a preexisting web application is posing a challenge. The issue arises as Jquery Mobile is interpreting all URL hashes by default. For example: mysite.com/#foo In this case, the hash 'foo' is being directe ...

Multiple change events triggered in AJAX interactions

Having a list of doctors in a dropdown menu with an ID of "doctors", I use AJAX to fetch related locations based on the selected doctor. These retrieved locations are then displayed in another dropdown menu with an ID of "locations". Subsequently, chan ...

Challenges with React Native's AsyncStorage

When I try to access data stored in asyncStorage using the 'getToken' and 'getMail' functions in the code snippet below, I encounter an issue where the data appears empty when I initially open the page on the emulator. However, upon sav ...

Exploring Angular 1.5 components: maximizing the potential of directives with ES6!

Within the directory labeled directives, I have created two files: directives.js and color.js I have imported directives into app.js Contents of directives.js: import angular from 'angular'; import ColorDirective from './color'; co ...

Display the tooltip only when the checkbox is disabled in AngularJS

My current setup includes a checkbox that is disabled based on a scope variable in Angular. If the scope variable is true, the checkbox stays disabled. However, if the scope variable is false, the checkbox becomes enabled. I am looking to implement a too ...

Arrange records in ascending order by phone number when multiple are returned on the same date

Currently, I am working on an Angular application that is designed to keep track of tuxedo rentals. The main feature of the app is a table that displays information from an array stored in the controller. The initial task I completed was listing the items ...

Renewed Promises: Exploring Promises in Angular JS

Revised with HTTP and initial code inspired by requests/Refer to the end of the post: Lately, I have been seeking help from the amazing SO community as I navigate through my AngularJS learning journey. I used to be a traditional C programmer but recently ...

When attempting to modify an object that was initialized outside of a function, I am unable to change its value, or sometimes the function may not run at all. This

Currently in the process of constructing a social network utilizing nodejs, my knowledge on the subject matter is quite novice. This marks my initial discourse on the topic, and I would greatly appreciate your comprehension. Within my social network frame ...

Modify the color of the panel header when the button is clicked

I am trying to modify the background color of my panel header using a button that changes the color scheme of my site. The button currently functions on AFO. Below is the stylesheet for the button: .AFO { background-color: #fff;} .AFO h1 { color: #00159d; ...

A guide to securely retrieving data from the Hono API endpoint using type safety within a Next.js application

Currently, I am using Hono as my API endpoint with Bun. Now, I am working on a new app with Next.js and I want to ensure type safety when fetching data from my API. I believe I can accomplish this through RPC. However, I am unable to locate AppType mention ...

Offspring maintain a certain position within the larger framework of their parent on a

When resizing the parent wrap container, how can I ensure that the pin (red dot) on the image maintains its relative position? To see the issue, resize the wrap container. #wrap{ position: absolute; width: 100%; height: 100%; top: 0; l ...

The gap persists even when overflow is used in CSS

My HTML table is set up with an overflow property to ensure it doesn't exceed a specific height, but the following div is not being positioned directly below the scrolling table as intended. Even though I am using overflow: hidden, I can still select ...

Executing a file function from another within a module function in ReactJS

I need to utilize the functions that are defined in the apiGet.js file: export let apiGet = () => { return 'File One'; } These functions are being called in another module called brand.js. Here is the code snippet: require("../action ...

What is the best way to retrieve the focused element in a shiny application?

I'm trying to figure out if there's a way to determine in shiny whether the user is focused on a text-field or select field. My website contains various elements such as plots, tables, numerical inputs, and buttons. Currently, I have implemented ...

An issue has been encountered in the OBJLoader module within the THREE.JS library

I've been delving into the teachings of the Three.js library through the book "Learning Three.js: The JavaScript 3D Library for WebGL" and I've also downloaded the example sets from the corresponding GitHub repository https://github.com/josdirkse ...