6

这是如何绑定 ko.observableArray 字符串的后续内容?

如何将可编辑的可观察字符串数组绑定到一组输入框?我不想绑定到对象数组,因为从服务器发送的底层 JSON 是字符串数组。

以下示例不起作用(在http://jsfiddle.net/LDNeA/尝试)。用可观察字符串绑定对象数组是可以的,但是直接绑定可观察字符串数组是行不通的,而且模型没有更新。

重要的是文本框中的条目被映射回模型。

JS:

var ViewModel = function() {
    this.value = ko.observable("hi")
    this.array1 = ko.observableArray([ko.observable("hi"), ko.observable("there")]);
    this.array2 = ko.observableArray([{ data: ko.observable("hi") }, { data: ko.observable("there") }]);
};

ko.applyBindings(new ViewModel());

HTML:

<div class='liveExample'>   
    <p><input data-bind='value: value' /></p> 
    <div data-bind="foreach: array1">
        <p><input data-bind='value: $data' /></p> 
    </div>
    <div data-bind="foreach: array2">
        <p><input data-bind='value: data' /></p> 
    </div>
</div>

<pre data-bind="text: ko.toJSON($data)"></pre>
4

4 回答 4

14

正如@Tyrsius 发布的链接所指出的,这是Knockout 中的一个错误(?)。

最简单的解决方法是使用$parent.items()[$index()],如本小提琴所示:http: //jsfiddle.net/r8fSg/。请注意,$parent.items()这是 foreach 中使用的项目的 observableArray。

<div data-bind="foreach: items">
    <p><input data-bind='value: $parent.items()[$index()]' /></p> 
</div>

<pre data-bind="text: ko.toJSON($data)"></pre>

和模型:

var ViewModel = function() {
    this.items = ko.observableArray([ko.observable("hi"), ko.observable("hi")]);
};

ko.applyBindings(new ViewModel());
于 2013-04-01T22:40:59.090 回答
3

问题是,当 Knockout 不是某物的属性时,它不会获得对源的引用。由于您只是向它传递一个函数,因此双向绑定失败。之前已经注意到这一点,在此处记录为问题,并且在此问题中解释了该行为。

这不是一个理想的解决方案,但您可以使用toJSON方法控制对象序列化。这将允许您生成看起来是字符串数组的内容,同时仍在observable您的应用程序中。

var Item = function(name){
    this.name = ko.observable(name);
};

Item.prototype.toJSON = function(){
    //special note: knockout already unwraps the observable for you
    return this.name;
};

这是小提琴


更新

有关仅使用绑定的解决方案,请参阅 slipheeds 答案,我更喜欢这种方法。留下这个答案以防其他人喜欢它

于 2013-04-01T19:06:29.023 回答
2

在 Knockout 3.0 及更高版本中,使用$rawData代替$data解决了这个问题。它也被称为解决方案@ https://github.com/knockout/knockout/issues/708#issuecomment-27630842

于 2016-01-27T17:32:19.587 回答
1

另一种解决方案是使用重复绑定 ( https://github.com/mbest/knockout-repeat ),它确实提供了此功能。这是您的示例更新为使用重复:http: //jsfiddle.net/LDNeA/1/

<div data-bind="repeat: array1">
    <p><input data-bind='value: $item' /></p> 
</div>
于 2013-04-02T00:35:38.423 回答