Knockout检测foreach中是否有任何可见

时间:2016-05-24 12:37:57

标签: jquery knockout.js

我有一个下拉菜单,由ul / li / a标签(Bootstrap)组成,在Knockout中动态绑定。我正在努力为其添加功能,以便根据您输入的内容进行过滤,方法是设置li的可见性,如果其选择与过滤字符串不匹配。这样可以正常工作但是如果它们都不匹配我想表现出某种"没有结果" DIV /消息。我还没有找到一个很好的方法来检查是否所有内容都不可见。

相关JS:

self.filteredOptions = function (e) {
    return $(e).find("a").text().toLowerCase().startsWith(self.filterString());
}

相关HTML:

<ul data-bind="foreach: ddlOptions">
    <li data-bind="visible: $parent.filteredOptions($element)">
        <a href="#" data-bind='event:{ click: function(){ $parent.Selection(Option)}}, attr:{"data-value": ID}, text: Option'></a>
    </li>
</ul>
<div> **If dropdown empty make this appear** </div>

ddlOptions是一个像[{ID : "123", Option: "option1"}, ..]

这样的对象数组

理想情况下,在消息div上做visible: ddlOptions().length == 0之类的事情会很好,但我只是隐藏那些li标签,而数据实际上并没有改变。是否有一种优雅的方式来检查是否仍然可见?

1 个答案:

答案 0 :(得分:2)

我创建一个仅包含已过滤选项的计算数组。您使用$element获取文字的方式对我来说有点倒退......(还是有其他要求?)

&#13;
&#13;
var vm = function() {

  this.options = ko.observableArray([{
    ID: "123",
    Option: "Option1"
  }]);

  this.filterString = ko.observable("");

  this.filteredOptions = ko.computed(function() {

    var originalOptions = this.options();
    var filterString = this.filterString().toLowerCase();

    if (!filterString) {
      return originalOptions;
    }

    return originalOptions.filter(function(option) {
      return option.Option
        .toLowerCase()
        .indexOf(filterString) === 0;
    });


  }, this);

};

ko.applyBindings(new vm());
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<ul data-bind="foreach: filteredOptions">
  <li data-bind="text: Option"></li>
</ul>
<div data-bind="visible: !filteredOptions().length">No matches</div>

<input data-bind="value: filterString, valueUpdate: 'keyup'" />
&#13;
&#13;
&#13;