如何将绑定上下文传递给自定义处理程序调用?

时间:2014-06-12 19:23:19

标签: javascript jquery knockout.js

我正在使用Knockout自定义处理程序更新我的对象:

ko.bindingHandlers.Tile = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var $element = $(element);

        var $parent = bindingContext.$parent || viewModel.$parent; // TODO: Clean up this mess

        /*
            Do lot of things using bindingContext.$parent, calculate elements dimension, populate fields etc.
        */
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        $(element).show();
    }
};

ko.bindingHandlers.TileColumn = {
    /*  another custom handler, we got a lot of those things  */
}

现在我实现了一个Resize函数,我可以在自定义处理程序中重用所有奇怪的逻辑来重绘/调整元素的大小。

var baseResize = this.Resize;
this.Resize = function () {
    baseResize.call(this);

    var tiles = this.Element.find('.tile');
    var tilesVM = this.DataSource.Items;

    for (var i = 0x0; i < tiles.length; i++) {

        tilesVM[i].$parent = this.ViewModel; // Clean up this mess too

        ko.applyBindingsToNode(tiles[i], null, tilesVM[i]);
    }
}

这有效,但感觉它不是正确的方法。我正在努力重构那些处理程序并从中调整调整大小的逻辑:不确定这是否是正确的方法。

在我们等待重构的同时,我想要一种更好的方式来调用applyBindings传递正确的bindingContext

注意我在这里做了一件非常难看的事情:

var $parent = bindingContext.$parent || viewModel.$parent; // TODO: Clean up this mess

在这里:

tilesVM[i].$parent = this.ViewModel; // Clean up this mess too

因为当我显式调用自定义处理程序时,bindingContext参数不包含父视图模型。

当然,当组件加载时,该处理程序可以正常运行而没有那种丑陋的凌乱线条,并且淘汰赛正在幕后做所有魔术。

1 个答案:

答案 0 :(得分:0)

罗伯特,谢谢你的时间。 该文档链接没有帮助,因为我有3个级别:TileParent,Tile和TileChilds,我只想调用Tile级别,如果没有applyBindingsToNode,我看不到这样做的方法。

但是这指出了绑定文档。在阅读this blog并挖掘ko源代码后,我意识到了一件很棒的事情:我可以将ViewModel或BindingContext作为参数传递。

起初我很伤心,我不能同时通过这两个,但我看到VM在BC $数据内。

最后我发现这个有用的 ko.contextFor(元素)

            for (var i = 0x0; i < tiles.length; i++) {
            var bindingContext = ko.contextFor(tiles[i]);

            ko.applyBindingsToNode(tiles[i], null, bindingContext);
        }

我还清理了我的处理程序回调

            var $parent = bindingContext.$parent;

一切仍然有效,但这次更清洁了!