从击倒.js的下拉菜单中过滤可观察数组

时间:2018-07-11 21:07:48

标签: knockout.js

几天前我才开始学习和使用基因敲除。我一直在浏览这些网站上的交互式教程以及其他相关的初学者练习,并且已经形成了基本的理解。

我正在尝试创建一个“日志处理程序”应用程序,该应用程序将基本上显示一些带有日志ID,描述和记录日期的硬编码错误日志。

我有一个带有三个过滤选项的下拉选择菜单,但我确实在努力使过滤工作正常。例如,过滤ID以仅显示ID在0到5000之间的日志。我尝试了各种方法,包括下面显示的代码,其中我尝试初始化数组元素,清除该数组,然后使用匹配的元素填充该数组if条件,最后显示该数组。但是,我不确定在哪里显示过滤后的数组,因为它将覆盖原始数组self.logs

查看

<span style="margin-left:40px">Filter <select data-bind="options: filters,optionsText : 'name', selectedOptions: chosenFilter, optionsCaption: 'Choose...'"></select></span>
<span style="margin-left:20px"><button data-bind="enable: chosenFilter, click: resetFilter">Reset filter</button></span>
<table style="border-collapse: separate; border-spacing: 25px;">
    <thead>
        <tr>
            <th>Log ID</th>
            <th>Description</th>
            <th>Date logged</th>
            <th></th>
        </tr>
    </thead>
    <tbody data-bind="foreach: logs">
        <tr>
            <td data-bind="text: id"></td>
            <td data-bind="text: errorDetails().description"></td>
            <td data-bind="text: errorDetails().date"></td>
            <td><a href="#" data-bind="click: $root.removeLog">Remove log</a></td>
        </tr>
    </tbody>
</table>

ViewModel

// Overall
    function ViewModel() {
        var self = this;

        // Class to represent details of individual logs
        function logDetails(id, errorDescription) {
            var self = this;
            self.id = id;
            self.errorDetails = ko.observable(errorDescription);
        };

        self.filters = [
            { name: "Log ID (0-5000)" },
            { name: "Log description (A-Z)" },
            { name: "Date logged (most recent first)" }],
            self.chosenFilter = ko.observable(),
            self.resetFilter = function () { self.chosenFilter(null) },


            // Non-editable data - would come from the server
            self.descriptions = [
                { description: "Error binding data", date: "08/07/2018" },
                { description: "Error requesting data", date: "09/07/2018" },
                { description: "Error submitting request", date: "05/07/2018" },
                { description: "Warning - User does not have have priviliges", date: "04/05/2018" },
                { description: "New Error", date: "xx/xx/xxxx" }
            ],


            // Editable data
            self.logs = ko.observableArray([
                new logDetails(0035, self.descriptions[0]),
                new logDetails(1468, self.descriptions[1]),
                new logDetails(9021, self.descriptions[2]),
                new logDetails(9021, self.descriptions[2]),
                new logDetails(4068, self.descriptions[3]),
                new logDetails(4068, self.descriptions[3]),
                new logDetails(1468, self.descriptions[1])
            ]),

            // Operations
            self.addLog = function () {
                self.logs.push(new logDetails("xxxx", self.descriptions[4]));
            },
            self.removeLog = function (log) { self.logs.remove(log) }

        filteredLogs: ko.observablearray([]),
           find0to5000: function() {
                var counter = filteredLogs().length;
                for (var i = 0; i < counter; i++) {
                    filteredLogs().pop();
                }

                ko.utils.arrayforeach(this.logs(), function (log) {
                    if (log.id() >= 0 || log.id() <= 5000) {
                        filteredLogs.push(log);
                    }
                });
            }

    };
    ko.applyBindings(new ViewModel());

我希望有人可以阐明我在哪里出了问题,因为我希望在接下来的几个月中更多地学习kickout.js。

1 个答案:

答案 0 :(得分:0)

您的filteredLogs应该是一个计算字段,并取决于初始日志数组和过滤器:

 this.filteredLogs = ko.computed(function () {
        if (!this.chosenFilter()) {
            return this.logs();
        }

        return ko.utils.arrayFilter(this.logs(), function (logItem) {
            return log.id() >= 0 || log.id() <= 5000;
        });
    }, this);

当您在计算变量主体中提到某些变量时-您的计算将建立对这些变量的依赖关系,并且当其中任何一个更改时-计算的将通过再次执行自己的主体来重新计算其ellt。

要谨慎地批量推送很多项目-因为每次推送都会触发计算的重新计算,并且可能导致性能问题。

此外,在您的html中,您应该将绑定更改为foreach: filteredLogs