在淘汰赛中进行实时表搜索(在keyup上调用函数)

时间:2015-09-02 01:26:55

标签: knockout.js

抱歉,我对淘汰赛有点新意我只是想在桌面上进行实时搜索,但是我似乎无法让我的模型功能能够触发关键事件。搜索框。这是小提琴。

http://jsfiddle.net/LkqTU/26466/

这是代码。

<div class="container">
    <table class="table table-condensed  table-hover">
        <thead>
            <tr>
                <th>First Name</th>
                <th>Last Name</th>
                <th>Department</th>
            </tr>
        </thead>
        <tbody data-bind='foreach: employees'>
            <tr>
                <td data-bind='text: firstName'></td>
                <td data-bind='text: lastName'></td>
                <td data-bind='text: department'></td>
            </tr>
        </tbody>
    </table>
     <h2 class="text-center">Search</h2>

    <div class="form">
        <div class="form-group">
            <label>first name:</label>
            <input type="search" class="form-control" data-bind="value: query valueUpdate: 'keyup' event: { keyup: search }" autocomplete="off" />
        </div>
    </div>
</div>

这是javascript

function employee(firstName, lastName, department) {
    this.firstName = ko.observable(firstName);
    this.lastName = ko.observable(lastName);
    this.department = ko.observable(department);
    this.isVisible = ko.observable(true);

}

function model() {
    var self = this;
    this.employees = ko.observableArray("");
    this.query = ko.observable("");
    this.search = function () {

        $.each(self.employees, function (i, item) {
            item.isVisible(false);
            if (item.firstName().toLowerCase().indexOf(this.query().toLowerCase()) >= 0) {
                item.isVisible(true);
            }

        });
    };
}

var mymodel = new model();

$(document).ready(function () {
    loaddata();
    ko.applyBindings(mymodel);
});

function loaddata() {
    mymodel.employees.push(new employee("Bob", "Jones", "HR"));
    mymodel.employees.push(new employee("Mary", "Smith", "HR"));
    mymodel.employees.push(new employee("Greg", "Black", "Finance"));
}

1 个答案:

答案 0 :(得分:4)

我建议使用可观察数组的强大功能来显示/隐藏搜索结果,而不是跟踪列表中的哪些项目在employee函数/对象中可见/隐藏。实现这一目标的一种方法是通过computed可观察对象,如下所示:

self.filteredEmployees = ko.computed(function () {
    var filter = self.query().toLowerCase();

    if (!filter) {
        return self.employees();
    } else {
        return ko.utils.arrayFilter(self.employees(), function (item) {
            return item.firstName().toLowerCase().indexOf(filter) !== -1;
        });
    }
});

每当更新computed内的任何可观察对象时,都会重新评估computed本身。因此,在您的情况下,这会有效地对您的搜索文本框值进行订阅(query在视图模型中可观察到。)

另一个变化是,您的标记现在需要foreach绑定到filteredEmployees computed而不是实际的employees可观察数组。

computed内部的逻辑执行以下操作:

  1. 检查是否在搜索输入文本框中输入了任何内容(query observable)。如果没有,那么整个employees可观察数组将从computed返回并绑定到foreach绑定。
  2. 如果在搜索输入文本框中输入了某些内容,则使用名为arrayFilter的内部Knockout帮助函数来遍历employees可观察数组中的每个项目。每次迭代都使用员工的名字(firstName observable)将该名称的小写版本与输入搜索输入文本框中的文本的小写版本进行比较(query观察到的)。嵌套的return语法最初可能看起来有点奇怪,但内部return填充外部return正在使用的可观察数组作为computed返回的值观察到的。过滤后的返回可观察数组可能是所有内容,中间没有任何内容,但它没有触及实际的employees可观察数组;从computed observable返回一个新的/不同的对象。
  3. 注意 - filter observable中的computed变量捕获用户输入内容的小写值。这消除了在每次循环迭代时强制搜索输入文本框值为小写的需要(节省时间和资源)。

    最后一次标记更改,而不是使用value绑定和updateValue绑定,更新后的jsFiddle现在使用较新的textInput绑定。对于较新版本的Knockout(3+),这是推荐的方法。它更高效,支持复制/粘贴/剪切到文本框,value绑定和updateValue绑定在这些文本框中挣扎。

    以下是textInput绑定的标记更改:

    <input type="search" class="form-control" 
           data-bind="textInput: query" autocomplete="off" />
    

    使用多个绑定

    您发布的代码缺少,(逗号)来分隔同一元素上的多个绑定。

    这是您发布的代码:

    <input type="search" class="form-control" 
           data-bind="value: query valueUpdate: 'keyup' event: { keyup: search }"
           autocomplete="off" />
    

    应该是这样的:

    <input type="search" class="form-control" 
           data-bind="value: query, valueUpdate: 'keyup', event: { keyup: search }"
           autocomplete="off" />
    

    注意 - 我更新了您的jsFiddle