Javascript 自定义绑定中的正确依赖性跟踪
我试图实现的是可视化地过滤由Javascript 自定义绑定中的正确依赖性跟踪,javascript,knockout.js,javascript-databinding,Javascript,Knockout.js,Javascript Databinding,我试图实现的是可视化地过滤由foreach绑定生成的表行,过滤掉的行的tr元素将被隐藏,而不是从DOM中删除。 当用户更改过滤器条件时,此方法可显著提高渲染性能。这就是为什么我不希望将foreach绑定到根据过滤条件更新的计算可观察数组。 我希望这个解决方案成为我可以在项目的其他地方使用的现成构建块 就我所熟悉的Knockout而言,最好的方法是实现自定义绑定 我打算使用这种绑定的方式如下: <tbody data-bind="foreach: unfilteredItems, visib
foreach
绑定生成的表行,过滤掉的行的tr
元素将被隐藏,而不是从DOM中删除。当用户更改过滤器条件时,此方法可显著提高渲染性能。这就是为什么我不希望将
foreach
绑定到根据过滤条件更新的计算可观察数组。我希望这个解决方案成为我可以在项目的其他地方使用的现成构建块 就我所熟悉的Knockout而言,最好的方法是实现自定义绑定 我打算使用这种绑定的方式如下:
<tbody data-bind="foreach: unfilteredItems, visibilityFilter: itemsFilter">
<tr>
...
</tr>
</tbody>
self.itemsFilter = function (item) {
var filterFromDate = filterFromDate(), // Observable
filterDriver = self.filterDriver(); // Observable too
return item && item.Date >= filterFromDate && (!filterDriver || filterDriver === item.DriverKey);
};
以下是到目前为止我已经完成的绑定实现:
/*
* Works in conjunction with the 'foreach' binding and allows to perform fast filtering of generated DOM nodes by
* hiding\showing them rather than inserting\removing DOM nodes.
*/
ko.bindingHandlers.visibilityFilter = {
// Ugly thing starts here
init: function (elem, valueAccessor) {
var predicate = ko.utils.unwrapObservable(valueAccessor());
predicate();
},
// Ugly thing ends
update: function (elem, valueAccessor) {
var predicate = ko.utils.unwrapObservable(valueAccessor()),
child = ko.virtualElements.firstChild(elem),
visibleUpdater = ko.bindingHandlers.visible.update,
isVisible,
childData,
trueVaueAccessor = function () { return true; },
falseVaueAccessor = function () { return false; };
while (child) {
if (child.nodeType === Node.ELEMENT_NODE) {
childData = ko.dataFor(child);
if (childData) {
isVisible = predicate(childData, child);
visibleUpdater(child, isVisible ? trueVaueAccessor : falseVaueAccessor);
}
}
child = ko.virtualElements.nextSibling(child);
}
}
};
ko.virtualElements.allowedBindings.visibilityFilter = true;
您是否看到丑陋的init
部分使用谓词调用,而不向其传递对象
如果没有这一点,如果在第一次敲除调用update
方法时,itemsFilter
filter函数不会调用foreach
绑定生成的行。因此,不会读取任何观察值,并且KO依赖项跟踪机制决定此绑定不依赖于我的视图模型中的任何观察值。
当过滤器可观测值(
filterFromDate
和filterDriver
)发生更改时,update
将不再被调用,整个过滤将无法工作
如何改进此实现(或问题的整个解决方法)为了避免对筛选函数进行丑陋的调用,这至少会使函数等待一个
未定义的值作为参数?您可以在tr
上使用可见的绑定,并使用$data
作为参数将其绑定到函数调用的结果。下面是一个小演示。无论选择哪个值,都会从表中过滤掉
var-vm={
行数:ko.observearray(['1','2','3']),
选定:可观察的(“一”),
isVisible:函数(行){
返回行!==vm.selected();
}
};
ko.应用绑定(vm)代码>
似乎您可以在tr
元素上使用一个可见的绑定。@Roy:我需要将它绑定到哪些可观察对象?这是一个非常简单的方法,它工作起来很有魅力!非常感谢。非常感谢你的帮助!