我正在开发一个简单的 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]));
}
}
};