Javascript Array Crossbrowser问题

时间:2013-10-29 13:07:13

标签: javascript arrays knockout.js momentjs

我正在开发一个简单的Web应用程序,用户可以按时间顺序评论文章(如博客文章评论)。每条评论都有一个时间戳。我使用KnockoutJS作为客户端视图模型,并且由于IE9中日期对象的问题,我使用MomentJS进行crossbrowser时间戳解析(每个注释的Timestamp属性实际上是MomentJS生成的对象)。数据来自作为JSON的REST端点到客户端,在客户端中,它在Knockout视图模型中实例化。我的文章模型的构造函数看起来像这样(缩短):

GC.ko.modelArticle = function (a) {
    this.Id = ko.observable(a.Id);
    this.Title = ko.observable(a.Title).extend({ required: true, minLength: 3 });
        :     //some more Properties
    this.Comments = ko.observableArray();
    if (util.isDefined(a.Comments)) {
        for (var i = 0; i < a.Comments.length; i++) {
            this.Comments.push(new GC.ko.modelComment(a.Comments[i]));
        }
    }
    this.Comments.sort(function (left, right) {
        return left.Timestamp == right.Timestamp ? 0 : (left.Timestamp < right.Timestamp ? -1 : 1);
    });
};

如您所见,如果JSON(a)包含注释,则会将这些注释推送到Knockout observableArray。之后我按时间顺序对数组进行排序,以便在UI中较旧的注释后显示较新的注释。

在Firefox和Chrome中,数组按升序排列。

在IE9中,它按降序排序。

这是否因为

而发生
  • Array()。push()函数的crossbrowser问题
  • 或Array()。sort()函数,
  • 或因为Knockout observable Arrays有排序问题,
  • 或者是因为我的代码中出现了一些错误?

编辑: comment.Timestamp是一个Knockout Observable。我尝试了两种变体:

首先返回一个普通的Javascript Date对象(在IE中有时间戳解析问题,所以我不得不修改它):

this.Timestamp = ko.observable(c.Timestamp)

第二次回归对象:

this.Timestamp = ko.observable(moment(c.Timstamp)
  • 'c'是评论的JSON

编辑2:事实证明,Knockout 2.2.1中observableArray()的sort()函数似乎是个问题。我将我的代码修改为以下内容(首先对普通的javascript数组进行排序,然后将元素推送到KO Observable Array),一切正常。这是代码:

GC.ko.modelArticle = function (a) {
    this.Id = ko.observable(a.Id);
    this.Title = ko.observable(a.Title).extend({ required: true, minLength: 3 });
        :     //some more Properties
    this.Comments = ko.observableArray();
    if (util.isDefined(a.Comments)) {
        a.Comments.sort(function(left,right) {
            return left.Timestamp == right.Timestamp ? 0 : (left.Timestamp < right.Timestamp ? -1 : 1);
        });

        for (var i = 0; i < a.Comments.length; i++) {
            this.Comments.push(new GC.ko.modelComment(a.Comments[i]));
        }
    }
};

1 个答案:

答案 0 :(得分:3)

鉴于.Timestamp是一个时刻,您应该使用.isBefore()和.isSame()比较方法,如下所示:

this.Comments.sort(function (left, right) {
    return left.Timestamp.isSame(right.Timestamp) ? 0 : (left.Timestamp.isBefore(right.Timestamp) ? -1 : 1);
});