我正在尝试为引用模板的 twitter boostrap 弹出框创建自定义绑定,但是一旦创建弹出框内的内容的绑定部分,我遇到了问题。
我以前看过这个问题,但我觉得它们大多都很混乱,而且我非常接近一个可重用的解决方案,它可以按照我的意愿使用模板。
http://jsfiddle.net/billpull/Edptd/
// Bind Twitter Popover
ko.bindingHandlers.popover = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var tmplId = ko.utils.unwrapObservable(valueAccessor());
var tmplHtml = $('#' + tmplId).html();
var uuid = guid();
var domId = "ko-bs-popover-" + uuid;
var tmplDom = $('<div/>', {
"class" : "ko-popover",
"id" : domId
}).html(tmplHtml);
options = {
content: tmplDom[0].outerHTML
};
var popoverOptions = ko.utils.extend(ko.bindingHandlers.popover.options, options);
console.log($(element));
console.log(element);
$(element).bind('click', function () {
$(this).popover(popoverOptions).popover('toggle');
ko.applyBindings(bindingContext, document.getElementById(domId));
});
},
options: {
placement: "right",
title: "",
html: true,
content: "",
trigger: "manual"
}
};
===编辑
根据下面的答案更新了代码,允许您在没有额外的 withProperties 绑定的情况下执行此操作
// Bind Twitter Popover
ko.bindingHandlers.popover = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
// read popover options
var popoverBindingValues = ko.utils.unwrapObservable(valueAccessor());
// set popover template id
var tmplId = popoverBindingValues.template;
// set popover trigger
var trigger = popoverBindingValues.trigger;
// get template html
var tmplHtml = $('#' + tmplId).html();
// create unique identifier to bind to
var uuid = guid();
var domId = "ko-bs-popover-" + uuid;
// create correct binding context
var childBindingContext = bindingContext.createChildContext(viewModel);
// create DOM object to use for popover content
var tmplDom = $('<div/>', {
"class" : "ko-popover",
"id" : domId
}).html(tmplHtml);
// set content options
options = {
content: tmplDom[0].outerHTML
};
// Need to copy this, otherwise all the popups end up with the value of the last item
var popoverOptions = $.extend({}, ko.bindingHandlers.popover.options);
popoverOptions.content = options.content;
// bind popover to element click
$(element).bind(trigger, function () {
$(this).popover(popoverOptions).popover('toggle');
// if the popover is visible bind the view model to our dom ID
if($('#' + domId).is(':visible')){
ko.applyBindingsToDescendants(childBindingContext, $('#' + domId)[0]);
}
});
return { controlsDescendantBindings: true };
},
options: {
placement: "right",
title: "",
html: true,
content: "",
trigger: "manual"
}
};