如何获取使用特定敲除绑定的所有元素的列表?
How to get a list of all elements that use a particular knockout binding?
knockout website 告诉我们如何从特定元素的自定义绑定内部访问该元素的所有绑定。
但是我想获取应用特定命名绑定的所有元素的列表。这可以通过敲除方法实现吗?
例如,我想向 knockout 询问我页面上所有使用可见绑定的元素的列表。
有趣的问题!
我要出去告诉你需要做 DOM traversal yourself. There is no Knockout util that does exactly what you want. And even then you'll have to hook deep into KO. This is based on some experience, as well as carefully peering through the 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);
在我的代码中,我还利用了 nodeHasBindings
、getBindings
和 getBindingsString
。后者有 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.
所以我假设前两个方法 是 接口 public 的一部分,因此可以安全地用于您的目的。无论如何,getBindingsString
对于您的目的来说并不是必需的,但我只是为了示例而将其包含在示例中。
knockout website 告诉我们如何从特定元素的自定义绑定内部访问该元素的所有绑定。
但是我想获取应用特定命名绑定的所有元素的列表。这可以通过敲除方法实现吗?
例如,我想向 knockout 询问我页面上所有使用可见绑定的元素的列表。
有趣的问题!
我要出去告诉你需要做 DOM traversal yourself. There is no Knockout util that does exactly what you want. And even then you'll have to hook deep into KO. This is based on some experience, as well as carefully peering through the 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);
在我的代码中,我还利用了 nodeHasBindings
、getBindings
和 getBindingsString
。后者有 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.
所以我假设前两个方法 是 接口 public 的一部分,因此可以安全地用于您的目的。无论如何,getBindingsString
对于您的目的来说并不是必需的,但我只是为了示例而将其包含在示例中。