我已经为twitter bootstrap popovers创建了一个自定义绑定,我使用它来在弹出窗口中显示双向绑定数据,但如果内容的大小在每个popover之间不同,则对齐关闭
http://jsfiddle.net/billpull/g6vH2/1
我不确定在这里发布的相关代码是什么样的,只要发布整个内容就可以查看演示文件的小提琴。
HTML
<!doctype html>
<html>
<body>
<br><br><br>
<div data-bind="foreach: items">
<span data-bind="text: label"></span>
<input type="checkbox" data-bind="checked: required" />
<button data-bind="popover: {template: 'settingsPopover', trigger: 'click'}">settings</button><br>
</div>
<script type="text/html" id="settingsPopover">
<h4><span class="icon-cog"> </span> Attributes</h4>
<label>Label</label>
<input type="text" data-bind="value: label, valueUpdate:'afterkeydown'" />
<label class="checkbox">
<input type="checkbox" data-bind="checked: required" /> Required
</label>
<ul data-bind="foreach: options">
<li data-bind="text: $data"></li>
</ul>
</script>
</body>
</html>
JS
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
};
function guid() {
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
// Bind Twitter Popover
ko.bindingHandlers.popover = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var $element = $(element);
// read popover options
var popoverBindingValues = ko.utils.unwrapObservable(valueAccessor());
// set popover title
var popoverTitle = popoverBindingValues.title;
// 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,
title: popoverTitle
};
// Need to copy this, otherwise all the popups end up with the value of the last item
var popoverOptions = $.extend({}, ko.bindingHandlers.popover.options, options);
// bind popover to element click
$element.bind(trigger, function (e) {
$(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]);
}
});
// Also tell KO *not* to bind the descendants itself, otherwise they will be bound twice
return { controlsDescendantBindings: true };
},
options: {
placement: "right",
title: "",
html: true,
content: "",
trigger: "manual",
container: 'body'
}
};
var ItemModel = function (data) {
var self = this;
self.label = ko.observable(data.label);
self.required = ko.observable(data.required);
self.options = ko.observableArray(ko.utils.arrayMap(data.options, function(option) {
return option;
}));
}
var ViewModel = function () {
var self = this;
self.initItems = [
{"label":"Item 1", "required": false, "options": [1,2,3,4,5,6]},
{"label":"Item 2", "required": true, "options": [1,2,3]},
{"label":"Item 3", "required": false, "options": []},
{"label":"Item 4", "required": true, "options": [1,2,3,6]}
];
self.items = ko.observableArray(ko.utils.arrayMap(self.initItems, function (item) {
return new ItemModel(item);
}));
};
$(function(){
ko.applyBindings(new ViewModel);
});
答案 0 :(得分:0)
当您将弹出窗口绑定中的click单击绑定到元素时,您初始化bootstrap popover然后appply绑定到后代。这就是为什么bootstrap popover错误地计算它的位置(没有嵌套的li-s,所以它们的高度为零)。之后淘汰赛附加了li-s元素和弹出高度变化,你必须重新计算弹出位置。
下次单击后重新初始化bootstrap popover但不应用绑定,这种情况下popover位置可以正确计算。
答案 1 :(得分:0)
可能你可以使用ko.applyBindingsToNode()。首先渲染模板然后绑定弹出框。
$element.bind(trigger, function (e) {
ko.applyBindingsToNode( tmplDom[0], {template : { name :'settingsPopover', data : viewModel}});
options = {
content: tmplDom[0].outerHTML,
title: popoverTitle
};
// Need to copy this, otherwise all the popups end up with the value of the last item
var popoverOptions = $.extend({}, ko.bindingHandlers.popover.options, options);
$(this).popover(popoverOptions).popover('show');
// }
});
答案 2 :(得分:0)
$element.bind(trigger, function (e) {
ko.applyBindingsToNode( tmplDom[0], {template : { name :'settingsPopover', data : viewModel}});
options = {
content: tmplDom[0].outerHTML,
title: popoverTitle
};
// Need to copy this, otherwise all the popups end up with the value of the last item
var popoverOptions = $.extend({}, ko.bindingHandlers.popover.options, options);
$(this).popover(popoverOptions).popover('show');
// }
});
由于某种原因,popover永远不会关闭!! :(