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

时间:2013-09-16 16:03:37

标签: javascript knockout.js custom-binding

我有一个具有多个可观察属性的淘汰模型:

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

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

使用bindingHandler时,只有在更新绑定的observable属性时才触发update方法,而不是在绑定的observables上的子属性发生更改时触发。

作为一种解决方法,我在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
    }
};

注意:这是一个简化的例子,我有一个通用的方法来订阅多个子观察者!

这是解决问题的好方法吗?或者我有一些内置的Knockout功能吗?

2 个答案:

答案 0 :(得分:4)

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);
    }
};

答案 1 :(得分:0)

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

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

简而言之,给定元素的所有绑定处理程序都在单个计算的observable的上下文中运行(文章中有一条注释,它可能会发生变化,因此每个绑定处理程序都在它的上下文中运行。自己的计算可观察量 - 这发生在3.0)。每次计算计算的observable中的函数时都会重新创建Knockout依赖项,这就是为什么每次都必须在更新中解包observable而不会丢失依赖项,就像你只在init中解包observable一样。

在文章中,他提出了一个选项,在绑定处理程序的init中创建一个计算的observable,以将你想要的任何observable绑定到某个函数:

        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);

这显然是危险的,所以要小心使用:)