I have a strange problem, at least I think it is strange.
The following will show nothing:
<input type="text" data-bind="value: selectedAddress.street1" />
But, if binded like this then it shows the correct value, but doesn't update (shows the value but does not seem to bind to object):
<input type="text" data-bind="value: ko.toJS($data).selectedAddress.street1" />
I checked if the selectedAddress object actually contains data with:
JSON.stringify(ko.toJS(selectedAddress), null, 2)
And it does
{
"id": 5631,
"street1": "Some Adress 43",
"street2": null,
"postcode": "15850",
"city": "GhostTown",
"country": "UK",
"addressTypes": []
}
How to get the input field to correctly bind to the object property and display/update value accordingly?
ViewModel:
var theViewModel = function() {
var self = this;
self.no = ko.observable();
self.name = ko.observable();
self.addresses = ko.observableArray([]);
self.selectedAddress = ko.observable(new Address());
...
}
What am I doing wrong?
I have a strange problem, at least I think it is strange.
The following will show nothing:
<input type="text" data-bind="value: selectedAddress.street1" />
But, if binded like this then it shows the correct value, but doesn't update (shows the value but does not seem to bind to object):
<input type="text" data-bind="value: ko.toJS($data).selectedAddress.street1" />
I checked if the selectedAddress object actually contains data with:
JSON.stringify(ko.toJS(selectedAddress), null, 2)
And it does
{
"id": 5631,
"street1": "Some Adress 43",
"street2": null,
"postcode": "15850",
"city": "GhostTown",
"country": "UK",
"addressTypes": []
}
How to get the input field to correctly bind to the object property and display/update value accordingly?
ViewModel:
var theViewModel = function() {
var self = this;
self.no = ko.observable();
self.name = ko.observable();
self.addresses = ko.observableArray([]);
self.selectedAddress = ko.observable(new Address());
...
}
What am I doing wrong?
Share Improve this question asked Jun 8, 2012 at 9:02 XatepXatep 3531 gold badge5 silver badges11 bronze badges 3-
2
Try
data-bind="value: selectedAddress().street1"
- I'm not sure whether implicit parenthesis are supported when concatenating observables. – Niko Commented Jun 8, 2012 at 9:15 - Niko, wanna do that as an answer, so it can be accepted? :) – Keith Nicholas Commented Jun 9, 2012 at 9:13
- Good idea, thanks. I've summed it up in a few sentences, please accept my answer in order to municate clearly that the answer to this question has been found. – Niko Commented Jun 9, 2012 at 23:39
3 Answers
Reset to default 3Parenthesis are optional only in some cases, but not when referring to a property of an object (that may or may not be the value of an observable). Therefore, you need to explicitly use parenthesis to get the value of the observable selectedAddress
. Then, you may refer to the property street1
of this object (parenthesis are now optional):
data-bind="value: selectedAddress().street1"
This is solution for one-way binding (value will not be updated).
Here is quote from KnockoutJS documentation http://knockoutjs./documentation/value-binding.html
If you reference something that is not a simple property, e.g., a plex JavaScript expression or a sub-property, KO will set the form element’s initial state to that value, but it will not be able to write any changes back when the user edits the form element. In this case it’s a one-time-only value setter, not a real binding.
To get two-way binding functionality, use templates. Something like:
<script type="text/html" id="someTemplate">
<input type="text" data-bind="value: street1" />
</script>
<div data-bind="template: { name: 'someTemplate', data: selectedAddress }"></div>
If someone had the same issue and wondered about this part
self.selectedAddress = ko.observable(new Address());
And you might ask whether there's a need to create a constructor or an object to fill up the ko.observable function, well you can, but if you don't like creating a model for this one, just add up an empty array and the parenthesis method should work.
example :
self.selectedAddress = ko.observable([]);
then :
selectedAddres().street1
This may not work for other instances but so far it worked on me. Thank you for this answer too, saved me a lot of time!