如何绑定可观察字符串的可编辑ko.observableArray?

时间:2013-04-01 18:47:07

标签: knockout.js knockout-2.0 knockout-mvc

这是How can I bind a ko.observableArray of strings?

的后续行动

如何将可编辑的可观察字符串数组绑定到一组输入框?我不想绑定到一个对象数组,因为从服务器发送的底层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 个答案:

答案 0 :(得分: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());

答案 1 :(得分:3)

问题是当Knockout不是某个东西的属性时,它不会获得对该来源的引用。由于您只是将它传递给函数,因此双向绑定失败。这是noted before,记录为an issue here,行为在this issue中被初始化。

这不是一个理想的解决方案,但您可以使用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;
};

这是the fiddle


更新

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

答案 2 :(得分:2)

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

答案 3 :(得分: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>