我正在编写自定义绑定,但作为其中的一部分,我需要通过javascript为可见绑定应用数据绑定。让它在前面工作似乎没有什么问题,但是当更新使用的observable时,绑定不会被重新评估。
在查看KO的源代码时,没有init事件,所以不确定是否在某个层发生了一些空间魔法,以使其重新评估可观察变化的dom元素,但我无法找到此信息。
那么是否有一些特定的方法来创建一个重新评估的人工绑定,或者我是否需要创建自己的订阅回调以继续重新评估可见绑定?
以下是我正在使用的代码:
ko.bindingHandlers.visible.update(element, isVisibleObservable, allBindingsAccessor, viewModel);
我知道我可以编写自己的节目并隐藏逻辑,但我只是觉得乍一看使用现有的绑定会更简单。
以下是代码用法的简单示例:
ko.bindingHandlers.someCustomBinding = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
var allBindings = allBindingsAccessor();
var customBindings = allBindings.someCustomBinding;
var someReferencedElement = $(customBindings.target)[0];
var isVisible = (customBindings.isDefault) ? true : false;
var visibleObservable = ko.observable(isVisible);
knockout.bindingHandlers.visible.update(someReferencedElement, visibleObservable, allBindingsAccessor, viewModel);
element.onclick = function() {
var toggledValue = !visibleObservable();
visibleObservable(toggledValue)
};
}
};
我已大大简化了方案,因此删除了参数验证等,但这应该突出主要用法和问题。当我单击带有自定义绑定的元素时,它会切换值(我在调试器中可以看到这一点),尽管它不会更新引用的DOM元素的可见性。
答案 0 :(得分:2)
需要从update
函数调用可见绑定update
函数,否则它将无法正常运行。只需创建更新功能并移动呼叫即可。此外,第二个参数是valueAccessor
,而不是原始的observable:
ko.bindingHandlers.someCustomBinding = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
var allBindings = allBindingsAccessor();
var customBindings = allBindings.someCustomBinding;
var someReferencedElement = $(customBindings.target)[0];
var isVisible = (customBindings.isDefault) ? true : false;
var visibleObservable = ko.observable(isVisible);
var visibleValueAccessor = function () { return visibleObservable; };
// store the stuff as data on the element so that
// it can be found in the update call
var data = { element: somereferencedElement, v: visibleValueAccessor };
ko.utils.domData.set(element, "__customBinding", data);
element.onclick = function() {
var toggledValue = !visibleObservable();
visibleObservable(toggledValue)
};
},
update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
var data = ko.utils.domData.get(element, "__customBinding");
knockout.bindingHandlers.visible.update(data.element, data.v, allBindingsAccessor, viewModel);
}
};
答案 1 :(得分:1)
查看此帖子 -
问题是您可以向Knockout添加新绑定并强制它们重新评估,但您要做的是将绑定应用于现有绑定并清理节点并重新评估,这是一个灰色区域在我提出的那个问题中表示。在这一点上,我将实现一个自定义绑定处理程序来执行您尝试使用显示/隐藏逻辑的操作,直到找到更稳定的解决方案。
您现在可以将代码合并到自定义绑定处理程序中 -
ko.bindingHandlers['visible'] = {
'update': function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
var isCurrentlyVisible = !(element.style.display == "none");
if (value && !isCurrentlyVisible)
element.style.display = "";
else if ((!value) && isCurrentlyVisible)
element.style.display = "none";
}
};
如果您展示了一个更好的示例并包含您的绑定处理程序,我可以帮助更新它。