knockoutjs:克隆一个observableArray-Object

时间:2014-07-11 12:42:19

标签: javascript jquery knockout.js

我想克隆/(深度)复制knockoutjs observableArray中的项目。

我无法在网上找到有关此问题的任何信息。每个人都想要克隆孔阵列;)

这是jsfiddle: http://jsfiddle.net/drchef/dCHMC/1/

你可以看到,我使用的是我在SO上找到的深层扫描方法。

this.cloneLine = function() {
    //This 2 lines is what i found on SO. Should work, but doesn not :(
    //cloning the second line (sry hardcoded...)
    var lastLine = this.lines()[1];
    this.lines.push(jQuery.extend(true, {}, lastLine));
};

在viewmodel-output中,您可以看到副本正在运行...但在内部新项目和克隆项目仍然引用相同的值。 如果更改新行中的值,它也会在原始行中更改。

背景: 我有一个输入网格,如果用户在最后一行并点击"输入"想要一个新行+最后一行的相同数据

我不想写一个方法或者克隆每一个数据的东西。在每次更改vm时,我都必须更新映射。 ;(

谢谢

2 个答案:

答案 0 :(得分:2)

您需要在Line viewmodel中展开observable。您可以使用ko.toJS实用程序方法执行此操作。 Demo

function Line(line) {
    this.a = ko.observable(line && line.a);
    this.b = ko.observable(line && line.b);
    this.c = ko.observable(line && line.c);
};

var ViewModel = function() {
    var self = this;

    this.lines = ko.observableArray([]); 

    this.cloneLine = function(line) {
        var l = new Line(ko.toJS(line));
        self.lines.push(l);
    };

    this.cloneLastLine = function() {
        var lines = self.lines(),
            line = lines[lines.length - 1];
        self.cloneLine(line);
    };
}

var model = new ViewModel();

//Initial Data
model.lines.push(new Line({ a: 0, b: 1, c: 2}));
model.lines.push(new Line({ a: 2, b: 1, c: 0}));

ko.applyBindings(model);

答案 1 :(得分:1)

要在Knockout中制作带有不同引用的副本,你真的需要创建一个副本......字面意思。使用您的方法,您从未真正打破任何链到现有的敲除绑定。正如您在下面的小提琴更新中看到的那样,您需要放弃“最后一条线路”。到一个扁平的JS对象然后创建一个新的'线'对象并将其传递给您的可观察数组。

http://jsfiddle.net/dCHMC/2/

this.cloneLine = function() {
    var lastLine = ko.toJS(this.lines()[1]);
    this.lines.push(new line(lastLine.a, lastLine.b, lastLine.c));
};