Knockout JS:observableArray.splice(0)没有克隆数组?

时间:2014-05-08 00:46:44

标签: javascript html knockout.js ko.observablearray

背景

我似乎无法丢失对原始数组的引用,我试图克隆。为了具体说明我的问题,假设我有以下内容。

  

JSBin http://jsbin.com/fehoq/168/edit

student.scores:  Array[3]
    0: 12
    1: 97
    2: 81

我的dropLowestScores方法然后打算在scores数组中找到两个最低值,复制它们并将它们放在属性lowest中。

 student.lowest:  Array[2]
    0: 12
    1: 81

不幸的是,虽然我在lowest中获得了正确的值,而不是从scores复制它们,但它们是拼接的。不仅如此,我的原始阵列中的所有值都已耗尽。

student.scores:  Array[0]

这可能有意义,因为我正在调用淘汰赛的splice方法,但是我在{{{{{{{{{ 1}}我第一次调用scores的数组!我不确定它是否重要,但我拼接的可观察数组包含可观察的数字。

有关详细信息,请参阅下面的脚本;有关完整内容,请参阅上面的JSBin。

请注意splice(0)只是我正在使用的模型。

JS

student

更新

正如edhedges指出的那样,this.dropLowestScores = function() { // find lowest scores for each student ko.utils.arrayForEach(_this.students(), function(student){ //sporting function for observable values in array var comparator = function(a,b){ if(a()<b()){ return -1; } else if(a() > b()){ return 1; } else { return 0; } }; // tmp is a sorted clone of scores var tmp = student.scores().sort(comparator).splice(0); // set lowest to last two values in tmp array student.lowest = tmp.splice((tmp.length-2),tmp.length); // see what I'm getting console.log(student.fullName()); console.log('student lowest: ' + student.lowest.length); console.log('student scores: ' + student.scores().length); }); }; 是正确的方法。 slice也与我的意图相反。

另一点是我在创建comparator之前无法排序,否则会更新我所希望的视图。

最终版本应如下所示。

tmp

1 个答案:

答案 0 :(得分:2)

您在这里遇到的主要问题是您致电splice并且应该致电slice

正如您所看到的,slice是您要完成的任务,但您使用了splice而没有第二个参数,因此您的阵列正在被擦除。

修复此问题后,您的comparator功能仍然存在问题。你返回的是最高的两个而不是最低的两个。

// updated dropLowestScores
this.dropLowestScores = function() {
    ko.utils.arrayForEach(_this.students(), function(student){
        var comparator = function(a,b){
          if(a()<b()){
            return 1;
          } else if(a() > b()){
            return -1;
          } else {
            return 0;
          }
        };                 
        var tmp = student.scores.slice(0).sort(comparator);
        student.lowest = tmp.splice((tmp.length-2),tmp.length);
        console.log(ko.toJSON(student.lowest));
        console.log(ko.toJSON(student.scores));
    });
};