我想克隆/(深度)复制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时,我都必须更新映射。 ;(
谢谢
答案 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对象然后创建一个新的'线'对象并将其传递给您的可观察数组。
this.cloneLine = function() {
var lastLine = ko.toJS(this.lines()[1]);
this.lines.push(new line(lastLine.a, lastLine.b, lastLine.c));
};