Я создал пользовательскую привязку для нокаута для twitter bootstrap popovers, и я использую это для отображения данных с двусторонней привязкой в popover, но если размер содержимого отличается между каждым popover выравнивание выключенTwitter Bootstrap Popovers Misaligned с разным размером контента
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);
});
http://billpull.github.com/knockout-bootstrap/
Вы можете думать о любом случае, чтобы обойти это, поскольку я не знаю, могу ли я применить привязки перед созданием popover. – BillPull
К сожалению, bootstrap и knockout немного несовместимы. В настоящее время bootstrap заменяет содержимое popover кодом html на открытом, это место, где теряются привязки нокаута. Также открытый метод содержит вычисления позиции, поэтому вы не можете пересчитывать его отдельно после применения popover.open и привязки нокаута. Поэтому я бы предложил переписать bootstrap popover - либо разрезать вычисления позиции для отдельного метода и запускать его после применения привязки нокаута или ... – Kasheftin
... изменить логику popover, чтобы открытые и скрытые методы изменяли только видимость содержимого popover, не влияя на структуру dom – Kasheftin