我希望实现一个绑定来搜索HTML表。
我考虑过实现自定义绑定并利用jQuery来解决繁重问题。自定义绑定方面是使其在我的解决方案中普遍可访问。我目前的解决方案仅由jQuery组成,并且不使用任何KnockoutJS功能。
问题:如何传入要搜索的“目标”表? ko.customBindings
只能访问它绑定的元素,我需要使用输入,所以我不知道是否有办法覆盖参数并传入目标id
的表格,或者其他什么。通过valueAccessor
获取搜索字词很容易,但我不知道是否可以使用
同样,我想让这个功能“升级和移动”,所以如果有一个更好的通用方法来解决这个问题,我当然不会意识到这一点,也没有发现它正在寻找解决方案。我假设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
}
};
答案 0 :(得分:7)
使用Knockout和MVVM模式通常明智的做法是保持View" dumb"仅仅反映(或修改,使用双向绑定)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());

<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>
&#13;
显然有一些细节需要解决(区分大小写,限制等),但总体思路是存在的。有很多不同的方法可以提高性能,但首先要检查你是否需要这样做;不要太早优化!您尚未在问题中指定任何实际标准,因此尝试此方法是您最好的选择。
这也可能是&#34; Knockout / MVVM&#34;风格解决方案我发现你通常会得到最干净的代码,如果你只是使用jQuery,如果你还使用了Knockout ......
如果您确实想要实际搜索&#34; HTML表格#34;,即过滤掉不是由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());
});
&#13;
<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>
&#13;
此外,还有很多细节需要解决(区分大小写和其他过滤细节),但我无法提出更具体的建议,因为您未在问题中提供任何细节。您必须根据自己的情况调整上述解决方案。
我的示例使用show
和hide
,但是&#34;提升&amp;移动&#34;你把tr
元素停放在另一个隐藏表中的解决方案在这里同样可以正常工作,因为Knockout 不可以控制table
DOM。