以敲除方式以编程方式应用可见绑定

时间:2014-02-28 15:36:13

标签: javascript knockout.js

我正在编写自定义绑定,但作为其中的一部分,我需要通过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元素的可见性。

2 个答案:

答案 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)

查看此帖子 -

Reapply bindings in knockout

问题是您可以向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";
    }
};

如果您展示了一个更好的示例并包含您的绑定处理程序,我可以帮助更新它。