3

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

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

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

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

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

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

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

4

2 回答 2

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);
    }
};
于 2013-09-16T16:27:27.093 回答
0

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

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

简而言之,给定元素的所有绑定处理程序都在单个计算的 observable 的上下文中运行(文章中有一个注释,这可能会改变,以便每个绑定处理程序在它自己的计算 observable 的上下文中运行 - 这发生在3.0)。每次计算计算的 observable 中的函数时,都会重新创建敲除依赖项,这就是为什么每次都必须在更新中解包 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);

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

于 2014-04-29T13:39:39.143 回答