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

Bry*_*ger 1 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>
Run Code Online (Sandbox Code Playgroud)

这是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"));
}
Run Code Online (Sandbox Code Playgroud)

Kar*_*son 6

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

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;
        });
    }
});
Run Code Online (Sandbox Code Playgroud)

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

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

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

  1. 检查是否在搜索输入文本框(queryobservable)中输入了任何内容。如果不是,则整个employeesobservable 数组从computed和绑定到foreach绑定返回。
  2. 如果在搜索输入文本框中输入了某些内容,则使用名为的内部 Knockout 辅助函数arrayFilter循环遍历employees可观察数组中的每个项目。每次迭代都使用员工的名字 ( firstNameobservable ) 将该姓名的小写版本与输入到搜索输入文本框 ( queryobservable )中的文本的小写版本进行比较。嵌套return语法乍一看可能有点奇怪,但内部return正在填充可观察数组,外部return使用该数组作为可观察数组的返回值;从observable返回一个新的/不同的对象。computed可观察对象的。过滤后返回的 observable 数组可能是一切,没有或介于两者之间,但它并没有触及实际employeescomputed

注意- observablefilter内部的变量computed捕获用户输入内容的小写值。这消除了在每次循环迭代时强制搜索输入文本框值小写的需要(节省时间和资源)。

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

这是textInput绑定的标记更改:

<input type="search" class="form-control" 
       data-bind="textInput: query" autocomplete="off" />
Run Code Online (Sandbox Code Playgroud)

使用多个绑定

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

这是您发布的代码:

<input type="search" class="form-control" 
       data-bind="value: query valueUpdate: 'keyup' event: { keyup: search }"
       autocomplete="off" />
Run Code Online (Sandbox Code Playgroud)

本来应该是这样的:

<input type="search" class="form-control" 
       data-bind="value: query, valueUpdate: 'keyup', event: { keyup: search }"
       autocomplete="off" />
Run Code Online (Sandbox Code Playgroud)

注意- 我已经更新了你的jsFiddle