Knockout.js - Simple "Hello World" Doesn't Work

I am making a very simple welcome world for js knockout (from http://goo.gl/lddLl ): but my code generates an error that I don't understand.

<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <title>AJAX Example</title> <script src="../Scripts/jquery-2.0.3.js"></script> <script src="../Scripts/knockout-3.0.0.debug.js"></script> <script> // Here my data model var ViewModel = function (first, last) { this.firstName = ko.observable(first); this.lastName = ko.observable(last); this.fullName = ko.computed(function () { // Knockout tracks dependencies automatically. It knows that fullName depends on firstName and lastName, because these get called when evaluating fullName. return this.firstName() + " " + this.lastName(); }, this); }; ko.applyBindings(new ViewModel("Planet", "Earth")); // This makes Knockout get to work </script> </head> <body> <p>First name: <input data-bind="value: firstName" /></p> <p>Last name: <input data-bind="value: lastName" /></p> <h2>Hello, <span data-bind="text: fullName"> </span>!</h2> </body> </html> 

calling ko.applyBindings raises an error:

Uncaught TypeError: Unable to read the 'nodeType' property from null knockout-3.0.0.debug.js: 2439

from the knockout-3.0.0.debug.js code:

 // Perf optimisation: Apply bindings only if... // (1) We need to store the binding context on this node (because it may differ from the DOM parent node binding context) // Note that we can't store binding contexts on non-elements (eg, text nodes), as IE doesn't allow expando properties for those // (2) It might have bindings (eg, it has a data-bind attribute, or it a marker for a containerless template) var isElement = (nodeVerified.nodeType === 1); 

I'm too ignorant to find out what I'm doing wrong ...

+8
javascript
source share
2 answers

2 ways to solve this, I think.

1 easiest way: wrap script inside

 $(document).ready(function() { your script goes here }); 

use the jQuery ready () function to delay initialization until the page loads.

2 move your script to:

 <p>First name: <input data-bind="value: firstName" /></p> <p>Last name: <input data-bind="value: lastName" /></p> <h2>Hello, <span data-bind="text: fullName"> </span>!</h2> 

HTML is parsed from top to bottom. if you place scripts in front of html elements, they can be run before some or all of the page elements are ready to interact with.

+13
source share

Your script is executed before the body is added to the DOM, the body is the default root node for binding. Put the script at the bottom like this:

 <!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <title>AJAX Example</title> <script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-3.0.0.js"></script> <script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-3.0.0.debug.js"></script> </head> <body> <p>First name: <input data-bind="value: firstName" /></p> <p>Last name: <input data-bind="value: lastName" /></p> <h2>Hello, <span data-bind="text: fullName"> </span>!</h2> <script> // Here my data model var ViewModel = function (first, last) { this.firstName = ko.observable(first); this.lastName = ko.observable(last); this.fullName = ko.computed(function () { // Knockout tracks dependencies automatically. It knows that fullName depends on firstName and lastName, because these get called when evaluating fullName. return this.firstName() + " " + this.lastName(); }, this); }; ko.applyBindings(new ViewModel("Planet", "Earth")); // This makes Knockout get to work </script> 

+2
source share

All Articles