淘汰赛性能 - 过滤可观察阵列

时间:2012-12-14 13:54:40

标签: performance knockout.js

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

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

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

我遇到的问题是按角色过滤1000个左右的用户需要几秒钟。按名称中的文本过滤非常快(几毫秒),但按角色过滤则不是。我已经放了一些时间码,问题是我用来检查用户是否有所选角色的方法,所以我只是想知道是否有更好的方法,也许使用一些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;
    });
});

1 个答案:

答案 0 :(得分:2)

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

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