knockout.js - 过滤表内容

标签 knockout.js

我正在寻找实现一个绑定(bind)来搜索一个 HTML 表。

我考虑过实现自定义绑定(bind)并使用 jQuery 来完成繁重的工作。自定义绑定(bind)方面是使其在我的解决方案中普遍可访问。我当前的解决方案仅由 jQuery 组成,不使用任何 KnockoutJS 功能。

问题:如何传递要搜索的“目标”表? ko.customBindings只能访问它绑定(bind)的元素,并且我需要使用输入,所以我不知道是否有办法覆盖参数并传入目标 id的 table ,什么的。通过 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
    }  
};

最佳答案

对于 Knockout 和 MVVM 模式,通常明智的做法是让 View 保持“哑”,仅反射(reflect)(或使用双向绑定(bind)修改)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>


显然有一些细节需要解决(区分大小写、限制等),但总体思路就在那里。有很多不同的方法可以提高性能,但首先要检查你是否需要这样做;不要太早优化!您没有在问题中指定任何实际的性能标准,因此尝试这种方法是您最好的选择。

这也可能是“Knockout/MVVM”风格的解决方案。我发现,如果您还使用 Knockout,则仅最少使用 jQuery,您通常会获得最干净的代码......

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

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>


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

我的示例使用 showhide ,但是您停放的“升降和移动”解决方案说tr不同隐藏表中的元素在这里同样可以正常工作,因为 Knockout 不受 table 的控制。 DOM。

关于knockout.js - 过滤表内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31188583/

相关文章:

javascript - 如何在 jquery 对话框中初始化 Google map ?

knockout.js - 为什么单击事件仅针对此 KoGrid 模板中的第一个元素触发?

javascript - knockout 自定义绑定(bind)且处理速度慢

knockout.js - applyBindingsToNode 和 html 边界

javascript - Knockout - 访问对象数组中的属性

knockout.js - 如何在调试时从可观察对象中找到所有订阅函数

jquery - 用knockout.js绑定(bind)表如何清除

javascript - knockout 绑定(bind)失败

jquery - ko.observableArray() 对于 1000+ <div> 元素来说非常慢

knockout.js - 使用 fromJS 更新后选项文本变成函数字符串