Knockout JS值不显示/绑定/更新,但可通过ko.toJS($data).value获得

Knockout JS value not showing/binding/updating but is available through ko.toJS($data).value

本文关键字:toJS ko data 获得 value 可通过 JS 显示 绑定 更新 Knockout      更新时间:2023-09-26

我有一个奇怪的问题,至少我认为这很奇怪。

以下内容将不显示任何内容:

<input type="text" data-bind="value: selectedAddress.street1" />

但是,如果像这样绑定,那么它会显示正确的值,但不会更新(显示值,但似乎没有绑定到对象):

<input type="text" data-bind="value: ko.toJS($data).selectedAddress.street1" />

我检查了选定的地址对象是否实际包含以下数据:

JSON.stringify(ko.toJS(selectedAddress), null, 2)

它确实如此

{
 "id": 5631,
 "street1": "Some Adress 43",
 "street2": null,
 "postcode": "15850",
 "city": "GhostTown",
 "country": "UK",
 "addressTypes": []
}

如何让输入字段正确绑定到对象属性并相应地显示/更新值?

视图模型:

var theViewModel = function() {
        var self = this;
        self.no = ko.observable();
        self.name = ko.observable();
        self.addresses = ko.observableArray([]);
        self.selectedAddress = ko.observable(new Address());
        ...
}

我做错了什么?

括号

仅在某些情况下是可选的,但在引用对象的属性(可能是也可能不是可观察量的值)时则不是可选的。因此,您需要显式使用括号来获取可观察selectedAddress的值。然后,您可以引用此对象的属性street1(括号现在是可选的):

data-bind="value: selectedAddress().street1"

这是单向绑定的解决方案(值不会更新)。

这是引用KnockoutJS文档 http://knockoutjs.com/documentation/value-binding.html

如果您引用的内容不是简单属性,例如,复杂的 JavaScript 表达式或子属性,KO 会将表单元素的初始状态设置为该值,但在用户编辑表单元素时,它将无法写回任何更改。在这种情况下,它是一个一次性的值设定器,而不是一个真正的绑定。

若要获取双向绑定功能,请使用模板。像这样:

<script type="text/html" id="someTemplate">
    <input type="text" data-bind="value: street1" />
</script>
<div data-bind="template: { name: 'someTemplate', data: selectedAddress }"></div>

如果有人有同样的问题并想知道这部分

self.selectedAddress = ko.observable(new Address());

你可能会问是否需要创建一个构造函数或对象来填充ko.observable函数,你可以,但是如果你不喜欢为此创建一个模型,只需添加一个空数组,括号方法应该可以工作。

例:

self.selectedAddress = ko.observable([]);

然后:

selectedAddres().street1

这可能不适用于其他情况,但到目前为止它对我有用。也谢谢你的回答,为我节省了很多时间!