1

我正在开发一个简单的 Web 应用程序,用户可以在其中按时间顺序评论文章(如对博客文章的评论)。每条评论都有一个时间戳。我将KnockoutJS用于客户端视图模型,并且由于 IE9 中日期对象的问题,我使用MomentJS进行跨浏览器时间戳解析(每个评论的时间戳属性实际上是 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() 函数的跨浏览器问题
  • 或 Array().sort() 函数,
  • 或者因为 Knockout observable Arrays 存在排序问题,
  • 还是因为我的代码中有一些错误?

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

首先返回一个普通的 Javascript 日期对象(在 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 数组),现在一切正常。这是代码:

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

1 回答 1

3

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

this.Comments.sort(function (left, right) {
    return left.Timestamp.isSame(right.Timestamp) ? 0 : (left.Timestamp.isBefore(right.Timestamp) ? -1 : 1);
});
于 2013-10-29T13:22:26.937 回答