javascript - Knockout JS : observableArray. splice(0) 不是克隆数组?

标签 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 数组中查找两个最低值,复制它们并将它们放入属性 最低

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

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

student.scores:  Array[0]

这可能是有道理的,因为我正在调用 knockout 的 splice 方法,但是我是在 scores 的副本上调用它> 我第一次调用 splice(0) 的数组!我不确定这是否重要,但我正在拼接的可观察数组由可观察数字组成。

请参阅下面的脚本了解详细信息,或查看上面的 JSBin 了解完整内容。

请注意,student 只是我正在使用的模型。

JS

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);
    });
};

更新

正如 edhedges 所指出的,slice 是正确的方法。比较器的排序也与我的意图相反。

进一步的一点是,在创建 tmp 之前我无法排序,否则它会更新 View ,这是我想要的。

最终版本应如下所示。

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().sort(comparator).slice(0);
        student.lowest = tmp.splice((tmp.length-2),tmp.length-1);
    });
};

最佳答案

您遇到的主要问题是您调用了splice,并且应该调用slice

如您所见slice是您想要完成的任务,但您使用了 splice没有第二个参数,因此您的数组被删除。

修复此问题后,您的比较器函数中仍然存在问题。您返回的是两个最高的值,而不是两个最低的值。

// 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));
    });
};

关于javascript - Knockout JS : observableArray. splice(0) 不是克隆数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23530872/

相关文章:

javascript - 使用 getElementsByTagName ('*' )/Wildcard 查找 ID 的一部分

javascript - 重置节点顺序并隐藏 event.srcElement

html - 将带有 Canvas 的 div 元素拖到另一个元素上

php - 如何使用 jquery 验证器检查用户名和电子邮件已经存在,除了数据库中的一个特定 id

javascript - 计算 knockout 中一些输入的总和

data-binding - Knockout.js 基于 css 类添加可见性 observable

javascript - 在 Javascript 中计算签名/哈希并与 C# 具有相同的结果

javascript - Angular 路由器不工作

html - 为什么 MDN 建议在视口(viewport)标签中使用 initial-scale=0.86 和 minimum-scale=0.86 来抑制水平滚动?

knockout.js - 如何使用 "Show more..."按钮部分显示 observableArray