最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Knockout JS value not showingbindingupdating but is available through ko.toJS($data).value - Stack Overflow

programmeradmin4浏览0评论

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
Add a ment  | 

3 Answers 3

Reset to default 3

Parenthesis 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!

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论