【问题标题】:How can I bind an editable ko.observableArray of observable strings?如何绑定可编辑的可观察字符串 ko.observableArray?
【发布时间】:2013-04-01 18:47:06
【问题描述】:

这是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>

【问题讨论】:

  • 这绝对是一个问题,但是如果将 JSON 作为简单数组发送回服务器是唯一的要求,您会接受一个将自身序列化为单个值的对象,以便 看起来 就像一个数组?
  • @Tyrsius - 如果答案是“这目前是 knockout.js 中的一个错误”或“这就是为什么这永远无法工作”,我会接受这个答案。 :)
  • 显然这是一个已记录的问题,我更新了我的答案

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


【解决方案1】:

正如@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());

【讨论】:

    【解决方案2】:

    问题在于,当 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


    更新

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

    【讨论】:

    • 谢谢,那些(错误)正是我想要的。解决方法也很好!
    • 顺便说一句,看起来最简单的解决方法是使用 value: $parent.list[$index()] 而不是 value: $data
    • 这绝对看起来更干净,你应该把它作为答案
    • 我有同样的问题,但是我使用了映射插件,所以我不必在我的模型上定义属性。有了这个,我不得不再次。在我的场景中,我会使用@slipheed 的解决方案。两个都不错!
    【解决方案3】:

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

    【讨论】:

    • 太棒了!这是正确的答案,而且效果很好。
    【解决方案4】:

    另一种解决方案是使用重复绑定 (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-03-22
      • 1970-01-01
      • 1970-01-01
      • 2014-06-23
      • 2012-11-02
      • 2017-11-25
      • 2012-08-23
      • 2019-09-23
      • 1970-01-01
      相关资源
      最近更新 更多