创建一个依赖于可观察量“树”的 Knockout 绑定处理程序

Creating a Knockout binding handler that depends on a 'tree' of observables

本文关键字:Knockout 程序 处理 绑定 观察 一个 依赖于 创建      更新时间:2023-09-26

>我有一个具有多个可观察属性的敲除模型:

var personViewModel = {
    name: ko.observable('Bob'),
    age: ko.observable(123)
};

我想创建一个呈现人员视图模型的自定义绑定。但是,我希望此绑定更新,如果有任何子属性,即 nameage 将更新。

使用 bindingHandler,更新方法仅在绑定可观察量属性更新时触发,而不是在绑定可观察量上的子属性更改时触发。

作为一种解决方法,我正在向init函数中的子属性添加订阅:

ko.bindingHandlers.foo = {
    init: function (element, valueAccessor, allBindingsAccessor,
                    viewModel, bindingContext) {
        // setup code goes here ... DOM elements inserted etc....
        valueAccessor().age.subscribe(function () {
            // Update the UI
        });
        valueAccessor().name.subscribe(function () {
            // Update the UI
        });
    },
    update: function (element, valueAccessor, allBindingsAccessor,
                      viewModel, bindingContext) {
        // Update the UI
    }
};

注意:这是一个简化的示例,我确实有一种通用方法来订阅多个子可观察量!

这是解决问题的好方法吗?还是我在这里忽略了一些内置的淘汰功能?

ko.toJS 将连接依赖项,因此如果您在更新中调用它,它将为您解析所有依赖项

http://jsfiddle.net/rMG8y/

ko.bindingHandlers.foo = {
    update: function(element, valueAccessor) {
        //Resolve dependency
        var dependency = ko.toJS(valueAccessor());
        //Do whatever
        console.log(dependency);
    }
};

除了前面提到的内容之外,我发现以下文章对于理解 KNOCKOUT 绑定处理程序如何处理依赖项非常有帮助:

http://www.knockmeout.net/2012/06/knockoutjs-performance-gotcha-3-all-bindings.html

简而言之,给定元素的所有绑定处理程序都在单个计算可观察量的上下文中运行

(文章中有一个注释,这可能会更改,以便每个绑定处理程序在其自己的计算可观察量的上下文中运行 - 这发生在 3.0 中)。 每次评估计算可观察量中的函数时,都会重新创建挖空依赖项,这就是为什么您每次都必须在更新中解包可观察量,以免像仅在 init 中解包可观察量那样丢失依赖项。

在本文中,他提供了一个选项,用于在绑定处理程序的 init 中创建计算可观察量,以将您想要的任何可观察量绑定到某个函数:

        var args = arguments;
        ko.computed(function ()
        {
            ko.utils.unwrapObservable(valueAccessor()/*or whatever observable you want to tie the update to*/);
            doUpdateLogic(/*args or whatever you need*/);
        }, this);

这显然是危险的,因此请小心使用:)