【问题标题】:How to get a list of all elements that use a particular knockout binding?如何获取使用特定敲除绑定的所有元素的列表?
【发布时间】:2015-03-26 13:46:44
【问题描述】:

knockout website 告诉我们如何从特定元素的自定义绑定内部访问该元素的所有绑定。

但是,我想获取应用了特定命名绑定的所有元素的列表。这可以通过淘汰赛方法实现吗?

例如,我想向 knockout 询问我的页面上使用可见绑定的所有元素的列表。

【问题讨论】:

  • 这个问题有XY Problem的提示。为什么你认为这是解决问题的方法?
  • @Jamiec,出于工具目的,在我页面的调试输出部分,我想显示具有特定绑定和计数的所有元素的列表。我想使用 ko 而不是另一个框架而不是纯脚本来显示此信息。
  • 好的,看起来很明智。希望我的评论没有走错路;)
  • @Jamiec,一点也不。在可能不最适合问题的先入为主的解决方案方向的背景下提出问题并不少见。我经常这样做,所以事实上我很高兴你问。
  • 我已经启动了jsfiddle 来尝试对此进行调查。但老实说,我正在苦苦挣扎,用那个小提琴也许其他人可能会有一个想法。将顶级 div 视为您的 html 页面(或任何容器元素),并且您正在尝试使用 visible 绑定绑定所有元素。一个问题是,一旦你有了这些元素,你想用它们做什么?不管怎样,我也会继续看看。

标签: knockout.js


【解决方案1】:

有趣的问题!

我要出去说你需要自己做DOM traversal。没有完全符合您要求的 Knockout 实用程序。即便如此,您也必须深入 KO。这是基于一些经验,以及仔细查看KO TypeScript definition(这可能是对 KO 导出功能的近乎完整概述)。

查看定义中的the relevant bit,您可以像这样使用KnockoutBindingProvider

var vm = {
  submodel: {
    name: ko.observable('apple'),
    description: ko.observable('fruit')
  },
  elementsWithTextBindings: ko.observable('')
};

vm.refresh = function() {
  var result = "";
  var all = document.getElementsByTagName("*");
  
  for (var i=0, max=all.length; i < max; i++) {
    var ctx = ko.contextFor(all[i]);
    
    if (ko.bindingProvider['instance'].nodeHasBindings(all[i])
        && !!ko.bindingProvider['instance'].getBindings(all[i], ctx).text) {
      var bindings = ko.bindingProvider['instance'].getBindingsString(all[i], ctx);
      result += "Elem with id=" + all[i].id + " has `text` binding ('" + bindings + "').\n";
    }
  }
  vm.elementsWithTextBindings(result);
};

ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div id="a" data-bind="with: submodel">
  <p id="b" data-bind="text: name, style: { color: 'red' }"></p>
  <p id="c" data-bind="text: description"></p>
  <input id="d" data-bind="value: name" />
</div>
All elements with `text` bindings:
<button id="e" data-bind="click: refresh">refresh!</button>
<pre id="f" data-bind="text: elementsWithTextBindings"></pre>

这利用了您可以从外部访问ko.bindingProvider 的事实。这似乎是by design,因为源将其导出为:

ko.exportSymbol('bindingProvider', ko.bindingProvider);

在我的代码中,我还使用了nodeHasBindingsgetBindingsgetBindingsString。后者有a comment

// The following function is only used internally by this default provider.
// It's not part of the interface definition for a general binding provider.

所以我假设前两个方法 是公共接口的一部分,因此可以安全地用于您的目的。无论如何,getBindingsString 对于您的目的并不是真正必要的,但我只是为了示例而将其包含在示例中。

【讨论】:

    猜你喜欢
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 2013-05-03
    • 1970-01-01
    • 2020-08-01
    • 2012-05-06
    • 1970-01-01
    相关资源
    最近更新 更多