抱歉,我对淘汰赛有点新意我只是想在桌面上进行实时搜索,但是我似乎无法让我的模型功能能够触发关键事件。搜索框。这是小提琴。
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"));
}
答案 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
内部的逻辑执行以下操作:
query
observable)。如果没有,那么整个employees
可观察数组将从computed
返回并绑定到foreach
绑定。arrayFilter
的内部Knockout帮助函数来遍历employees
可观察数组中的每个项目。每次迭代都使用员工的名字(firstName
observable)将该名称的小写版本与输入搜索输入文本框中的文本的小写版本进行比较(query
观察到的)。嵌套的return
语法最初可能看起来有点奇怪,但内部return
填充外部return
正在使用的可观察数组作为computed
返回的值观察到的。过滤后的返回可观察数组可能是所有内容,中间没有任何内容,但它没有触及实际的employees
可观察数组;从computed
observable返回一个新的/不同的对象。 注意 - 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