我正在使用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
参数不包含父视图模型。
当然,当组件加载时,该处理程序可以正常运行而没有那种丑陋的凌乱线条,并且淘汰赛正在幕后做所有魔术。
答案 0 :(得分:0)
但是这指出了绑定文档。在阅读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;
一切仍然有效,但这次更清洁了!