【问题标题】:Knockout Performance - Filtering an Observable Array淘汰赛性能 - 过滤可观察数组
【发布时间】:2012-12-15 01:02:43
【问题描述】:

我是 Knockout 的新手,我正在尝试在显示系统用户和每个用户拥有的角色的页面上使用它。

数据位于observableArray 的用户中。用户对象有一个角色属性,它是另一个observableArray。第二个数组包含每个角色的对象,带有一个 ID 和一个布尔“授予”属性。

我希望能够显示所有具有特定角色的用户,因此每个角色都有一个复选框 - 当检查其中一个时,列表应显示该角色的用户。

我遇到的问题是按角色过滤大约 1,000 个用户需要几秒钟的时间。按名称中的文本过滤非常快(几毫秒),但按角色过滤则不然。我已经放入了一些计时代码,问题是我用来检查用户是否具有所选角色的方法,所以我只是想知道是否有更好的方法,也许使用一些 Knockout魔法。

下面是我用来进行过滤的视图模型上的 ko.computed。结果表绑定到这个函数。

self.filteredUsers = ko.computed(function () {

    var textFilter = self.filter();          // this is an observable bound to a text field
    var checkedRoles = self.selectedRoles(); // this is a computed, which returns an array of checked roles

    return ko.utils.arrayFilter(self.users(), function (user) {

        var match = true;

        if (user.displayName.toLowerCase().indexOf(textFilter.toLowerCase()) == -1) {
            match = false;
        }

        // for each ticked role, check the user has the role
        for (var i = 0; i < checkedRoles.length; i++) {
            var roleMatch = false;
            for (var j = 0; j < user.roles().length; j++) {
                if (user.roles()[j].roleId === checkedRoles[i].roleId && user.roles()[j].granted()) {
                    roleMatch = true;
                    break;
                }
            }
            if (!roleMatch) {
                match = false;
            }
        }

        return match;
    });
});

【问题讨论】:

    标签: performance knockout.js


    【解决方案1】:

    我认为一个好的优化是创建一个在你的用户对象上计算的grantedRoles。此计算将返回一个可用作索引的对象,将包含由角色的唯一标识符作为键的属性,并且仅包含已授予的角色。

    然后在filteredUsers 中,您将针对每个选中的角色检查grantedRoles 对象,而不是为每个选中的角色循环遍历user.roles()

    【讨论】:

    • 谢谢瑞恩 - 这当然有帮助。之前需要 3,500 毫秒到 4,000 毫秒。 grantRoles 计算将其缩短到 200 多毫秒。
    猜你喜欢
    • 2012-09-08
    • 2015-10-05
    • 1970-01-01
    • 2014-11-05
    • 2012-07-07
    • 2015-01-25
    • 2015-06-22
    • 2013-05-01
    相关资源
    最近更新 更多