我希望实现一个绑定来搜索HTML表.
我考虑过实现一个自定义绑定并利用jQuery进行繁重的工作.自定义绑定方面是使其在我的解决方案中普遍可访问.我目前的解决方案仅包含jQuery,并且不使用任何KnockoutJS功能.
问题:如何传入要搜索的"目标"表?ko.customBindings
只能访问它绑定的元素,我需要使用输入,所以我不知道是否有办法覆盖参数并传入id
表的目标或其他东西.获取搜索词很容易通过valueAccessor
,但我不知道我是否可以使用
同样,我想让这个功能"提升和移动",所以如果有一个更好的通用方法来解决这个问题,我当然不会意识到这一点,也没有发现它寻找解决方案.我假设a customBinding
是一个很好的解决方案,因为我已经看到它被如何使用,但不会反对其他解决方案.
我想的是:
ko.bindingHandlers.searchTable = {
update: function(element, valueAccessor, tableIdToSearch) {
var term = ko.unwrap(valueAccessor());
//check if table exists
// $.each(tableIdToSearch).find("tr"), function() .. use term
}
};
Run Code Online (Sandbox Code Playgroud)
通常使用Knockout和MVVM模式,保持View"哑"通常是明智的,仅仅反映(或修改,使用双向绑定)ViewModel的当前状态.
我不是100%肯定"搜索HTML表格"的意思,但搜索表格数据本身对我来说更有意义.对于中小型案例,computed
可观察数组可以为您完成工作,如下所示:
var ViewModel = function() {
var self = this;
self.filter = ko.observable('');
self.items = ko.observableArray(["apples", "apple pie", "apple sauce", "pumpkin pie", "peaches"]);
self.filteredItems = ko.computed(function() {
var filter = self.filter();
if (!filter) { return self.items(); }
return self.items().filter(function(i) { return i.indexOf(filter) > -1; });
});
};
ko.applyBindings(new ViewModel());
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
Search: <input data-bind="textInput: filter" />
<table>
<tbody data-bind="foreach: filteredItems">
<tr><td data-bind="text: $data"></td></tr>
</tbody>
</table>
Run Code Online (Sandbox Code Playgroud)
显然有一些细节需要解决(区分大小写,节流等),但总体思路是存在的.有很多不同的方法可以提高性能,但首先要检查你是否需要这样做; 不要太早优化!您尚未在性能问题中指定任何实际标准,因此尝试此方法是您最好的选择.
这也可能是"Knockout/MVVM"风格解决方案.我发现你通常会得到最干净的代码如果你只使用jQuery,如果你也使用Knockout ......
如果你确实想要实际搜索"HTML表",即过滤掉不是由Knockout生成的DOM,但仍然使用自定义绑定,那是可能的.以下是一个示例方法:
ko.bindingHandlers["filterTable"] = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var filter = ko.utils.unwrapObservable(valueAccessor());
$(element).find('tr').each(function(index, row) {
if ($(row).find('td:contains("'+filter+'")').length > 0) {
$(row).show();
}
else {
$(row).hide();
}
});
}
};
$(function() {
var ViewModel = function() {
var self = this;
self.filter = ko.observable('');
};
var items = ["apples", "apple pie", "apple sauce", "pumpkin pie", "peaches"];
ko.applyBindings(new ViewModel());
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
Search: <input data-bind="textInput: filter" />
<table data-bind="filterTable: filter">
<tbody>
<tr><td>apples</td></tr>
<tr><td>apple pie</td></tr>
<tr><td>apple sauce</td></tr>
<tr><td>pumpkin pie</td></tr>
<tr><td>peaches</td></tr>
</tbody>
</table>
Run Code Online (Sandbox Code Playgroud)
同样,还有很多细节需要解决(区分大小写和其他过滤细节),但我不能提出更具体的建议,因为你没有在你的问题中提供任何细节.您必须根据自己的情况调整上述解决方案.
我的例子使用show
和hide
,而是一个"升降机及移动"解决方案,您帕克说tr
在不同的隐藏的表元素来完成工作在这里很好,因为淘汰赛是不是在控制table
DOM.