javascript - 重新评估仅取决于可观察数组的 Knockout 计算

标签 javascript arrays knockout.js

我的 Appmodel 由一组可观察的评论组成

self.comments=ko.observableArray([]);  // Default Value is an empty array
/*
   Here comes some code to initially fill the observable array 
   with items from an JSON Response
*/

此外,我有两个计算应该代表第一个评论和最后一个评论

self.firstComment = ko.computed(function () {
    var sorted = self.comments.sort(function (left, right) {
        return left.Id() - right.Id();
    });
    return sorted[0];
});

self.lastComment = ko.computed(function () {
    var sorted = self.comments.sort(function (left, right) {
        return left.Id() - right.Id();
    });
    return sorted[sorted.length - 1];
});

这在初始化应用程序时非常有效(从服务器加载 JSON,构建 App 模型...),但是当我向数组添加注释时,计算无法识别数组项的数量已更改(据我了解,可观察数组只是观察数组属性本身的可观察对象)。所以当我这样做时:

self.comments.push(aNewCommentObject);

self.lastComment 仍然绑定(bind)到数组项,它是在应用程序最初加载时。

我找到了 this blog post如何通过引入虚拟可观察对象来强制计算,但我不喜欢这种方法。 observableArray 的使用目的是什么?如何使用?

其他挑战:我希望在任何情况下都对 observableArray 项目进行排序(因为它是一个评论提要,应该按时间顺序排序)。我尝试使用计算的 commentsSorted 来做到这一点,但也有问题,当 observableArray 有新项目时,它不会更新,所以这里有同样的问题。这就是为什么我每次都在 firstComment 和 lastComment 中排序的原因。

最佳答案

尝试展开注释以触发 Knockout 的依赖跟踪:

self.firstComment = ko.computed(function () {
    var sorted = self.comments().sort(function (left, right) {
        // -------------------^^ !
        return left.Id() - right.Id();
    });
    return sorted[0];
});

或(同样的事情):

self.firstComment = ko.computed(function () {
    var sorted = ko.unwrap(self.comments).sort(function (left, right) {
        return left.Id() - right.Id();
    });
    return sorted[0];
});

当然你可以把它抽象成一个单独的计算。

self.commentsSorted = ko.computed(function () {
    return self.comments().sort(function (left, right) {
        return left.Id() - right.Id();
    });
});

self.firstComment = ko.computed(function () {
    return ko.unwrap(self.commentsSorted)[0];
});

由于计算缓存了它们的返回值(就像所有其他可观察对象一样),您无需担心多次调用 self.commentsSorted。它只会在底层可观察数组有机会时重新计算。

关于javascript - 重新评估仅取决于可观察数组的 Knockout 计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20974917/

相关文章:

javascript - 在查询字符串中传递多个值

javascript - javascript 中的颜色相等

Javascript 在同一张图片上单击播放和暂停歌曲

javascript - Chrome,FileReader API,event.target.result === ""

c - 在函数中传递数组以对其元素求和

php - 替换 php 数组中的所有键

javascript - 我应该在 AngularJS 中使用关联数组吗?

c# - knockout View 模型+所选项目->嵌套列表 "not defined"

javascript - knockout 计算触发次数过多

javascript - 使用对象继承时 Knockout 映射的问题