筛选表内容 [英] Filter Table Contents

查看:49
本文介绍了筛选表内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找实现搜索HTML表的绑定.

I am looking to implement a binding to search an HTML table.

我考虑过实现自定义绑定并利用jQuery进行繁重的工作.自定义绑定方面是使其在我的解决方案中可普遍访问.我当前的解决方案仅包含jQuery,并且不使用任何KnockoutJS功能.

I thought about implementing a custom binding and utilizing jQuery for the heavy lifting. The custom binding aspect is to make it universally accessible within my solution. My current solution consists solely of jQuery and doesn't use any KnockoutJS functionality.

问题:如何传递要搜索的目标"表? ko.customBindings仅能访问绑定到的元素,并且我需要使用输入,所以我不知道是否有一种方法可以覆盖参数并传入表的目标id,或者其他的东西.通过valueAccessor可以很容易地获得搜索词,但是我不知道是否可以使用

The problem: How can I pass in a "target" table for which to search? ko.customBindings only have access to the element which it is bound to, and I need to use an input, so I didn't know if there was a way to override a parameter and pass in the target id of the table, or something. Getting the search term would be easy via the valueAccessor, but I didn't know if I could use

同样,我想使此功能提升并移动",因此,如果有更好的通用方法可以解决此问题,我当然不会意识到,也没有发现它正在寻找解决方案.我假设customBinding是一个很好的解决方案,因为我已经看到了它的用法,但不会与其他解决方案抗衡.

Again, I want to make this functionality "lift & move," so if there's a better general way to go about this I'm certainly not aware of it nor have I discovered it searching for a solution. I'm under the assumption that a customBinding is a good solution because of how I've seen it being used, but would not argue against other solutions.

我在想类似的东西:

ko.bindingHandlers.searchTable = {
    update: function(element, valueAccessor, tableIdToSearch) {
        var term = ko.unwrap(valueAccessor());        
        //check if table exists
        // $.each(tableIdToSearch).find("tr"), function() .. use term
    }  
};

推荐答案

一般而言,使用Knockout和MVVM模式,明智的做法是将View保持哑巴",仅反映(或使用双向绑定进行修改)当前ViewModel的状态.

With Knockout and the MVVM pattern in general it's often wise to keep the View "dumb", merely reflecting (or modifying, with two-way bindings) the current state of the ViewModel.

我不确定100%搜索HTML表格"的含义,但是搜索表格数据本身对我来说更有意义.对于中小型情况,computed可观察数组可以为您完成工作,如下所示:

I'm not 100% sure what you mean by "search an HTML table", but it would make more sense to me to search the tabular data itself. For small and medium size cases a computed observable array could do the work for you, like this:

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>

很显然,有一些细节需要解决(区分大小写,节流等),但是总的思路就在那里.有许多种提高性能的方法,但是首先请检查您是否甚至需要执行此操作;不要太早优化!您尚未在性能问题中指定任何实际标准,因此尝试此方法是您的最佳选择.

Obviously there are a few details to iron out (case sensitivity, throttling, etc), but the general idea is there. There's many different ways to up the performance, but first check if you even need to do that; don't optimize too early! You haven't specified any actual criteria in the question for performance, so just trying this approach is your best bet.

这也可能是淘汰赛/MVVM"风格的解决方案.我发现,如果您还使用Knockout,则只需最少使用jQuery,通常就能得到最干净的代码.

This is also probably the "Knockout/MVVM" style solution. I find that you typically get cleanest code if you only minimally use jQuery if you're also using Knockout...

如果您确实确实想实际搜索"HTML表",即过滤不是由Knockout生成的DOM,但仍使用自定义绑定,则 是可能的.这是解决该问题的一种示例方法:

If you really do want to actually search a "HTML table", i.e. filter DOM not generated by Knockout, but still use a custom binding, that is possible. Here's one example way to go about that:

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());  
});

<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>

同样,有许多细节需要解决(区分大小写和其他过滤细节),但是我无法提出更具体的建议,因为您没有在问题中提供任何细节.您必须根据自己的情况调整以上解决方案.

Again, lots of details to work out (case sensitivity and other filtering details), but I can't make a more specific suggestion because you haven't provided any specifics in your question. You'd have to adapt the above solution to your own situation.

我的示例使用showhide,但是在其中将tr元素停放在其他隐藏表中的抬升和移动"解决方案在这里同样可以正常工作,因为Knockout是 not 控制table DOM.

My example uses show and hide, but a "lift & move" solution where you park said tr elements in a different hidden table would work equally fine here, because Knockout is not in control of the table DOM.

这篇关于筛选表内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆