Reputation: 33880
I am learning knockout and this is my first ever example of it, so please be gentle.
I just want a one-way binding from the model to the textboxes, i.e, whatever is in the model must be displayed in the text boxes. I do not want to create observables yet.
Here is what I have, but when I run this code, the text boxes do not contain the model values, and the console reports an error:
TypeError: c is null
Here is my code:
1.html
<html>
<head>
<meta charset="utf-8"/>
<script type='text/javascript' src='knockout-3.4.0.js'></script>
<script type='text/javascript' src='1.js'></script>
</head>
<form id = "frm" name = "frm">
<fieldset>
<legend>Your friend's basic information</legend>
<div>
<label for = "FirstName">First Name</label>
<input type = "text" name = "FirstName" id = "txtFirstName" data-bind = "value: friend.firstName" />
</div>
<div>
<label for = "LastName">Last Name</label>
<input type = "text" name = "LastName" id = "txtLastName" data-bind = "value: friend.lastName" />
</div>
</fieldset>
</form>
</html>
1.js
var model =
{
friend :
{
firstName : 'Sathyaish',
lastName : 'Chakravarthy'
}
};
ko.applyBindings(model);
It looks like knockout isn't able to bind a nested property. Since the property I am binding to isn't directly a member of the model
object, but it is instead nested inside model.friend
, it isn't able to bind it.
Surely it can't be that I cannot have a hierarchical model and that I can only bind if the properties are top-level members of the model
object?
I am most likely doing something wrong with the syntax.
Upvotes: 0
Views: 50
Reputation: 714
You will need to use mapping library to do that. When you use nested properties like a class you need to use mapping. check it out: Plugin Knockout Mapping
Your code wil be some like that:
var viewModel = function () {
var _vm = null,
init = function () {
_vm = {
friend : ko.mapping.fromJS({
firstName : 'Sathyaish',
lastName : 'Chakravarthy'
}),
change: function(){
_vm.friend.firstName('first name changed');
}
};
ko.applyBindings(_vm, $('#frm').get(0));
}
return {
init: init
}
}();
i have that scenario all the time. I put in JSFIDDLE check it out
Upvotes: 0
Reputation: 105547
If you don't pass rootElement
to apply bindings, it's going to use window.document.body
. However, if you script is loaded in head
section, the body
is not available at that moment. So you need to move your 1.js
loading inside the body like this:
<html>
<head>
<meta charset="utf-8"/>
<script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-debug.js'></script>
</head>
<body>
<form id = "frm" name = "frm">
<fieldset>
<legend>Your friend's basic information</legend>
<div>
<label for = "FirstName">First Name</label>
<input type = "text" name = "FirstName" id = "txtFirstName" data-bind = "value: friend.firstName" />
</div>
<div>
<label for = "LastName">Last Name</label>
<input type = "text" name = "LastName" id = "txtLastName" data-bind = "value: friend.lastName" />
</div>
</fieldset>
</form>
<script type='text/javascript' src='1.js'></script>
</body>
</html>
Upvotes: 1