我是淘汰赛的新手。我正在使用淘汰赛和bootstrap 3.3.6(最新)。我需要通过knockout-bootstrap自定义绑定处理程序单击外侧关闭bootstrap popover。我为bootstrap 3自定义绑定处理程序获得了一些插件。但是我需要在点击身体时关闭弹出窗口。
这是我的sample Fiddle
var guid = (function(s4) {
return function() {
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
};
})(function() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
});
// Outer HTML
if (!$.fn.outerHtml) {
$.fn.outerHtml = function () {
if (this.length === 0) {
return false;
}
var elem = this[0], name = elem.tagName.toLowerCase();
if (elem.outerHTML) {
return elem.outerHTML;
}
var attrs = $.map(elem.attributes, function (i) {
return i.name + '="' + i.value + '"';
});
return "<" + name + (attrs.length > 0 ? " " + attrs.join(" ") : "") + ">" + elem.innerHTML + "</" + name + ">";
};
}
// Bind Bootstrap Popover
ko.bindingHandlers.popover = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var $element = $(element);
var popoverBindingValues = ko.utils.unwrapObservable(valueAccessor());
var template = popoverBindingValues.template || false;
var options = popoverBindingValues.options || {title: 'popover',placement:'bottom'};
var data = popoverBindingValues.data || false;
var controlDescendants = popoverBindingValues.controlDescendants;
if (template !== false) {
if (data) {
options.content = "<!-- ko template: { name: template, if: data, data: data } --><!-- /ko -->";
}
else {
options.content = $('#' + template).html();
}
options.html = true;
}
$element.on('shown.bs.popover', function(event) {
var popoverData = $(event.target).data();
var popoverEl = popoverData['bs.popover'].$tip;
var options = popoverData['bs.popover'].options || {};
var button = $(event.target);
var buttonPosition = button.position();
var buttonDimensions = {
x: button.outerWidth(),
y: button.outerHeight()
};
ko.cleanNode(popoverEl[0]);
if (data) {
ko.applyBindings({template: template, data: data}, popoverEl[0]);
}
else {
ko.applyBindings(viewModel, popoverEl[0]);
}
var popoverDimensions = {
x: popoverEl.outerWidth(),
y: popoverEl.outerHeight()
};
popoverEl.find('button[data-dismiss="popover"]').click(function() {
button.popover('hide');
});
switch (options.placement) {
case 'right':
popoverEl.css({
left: buttonDimensions.x + buttonPosition.left,
top: (buttonDimensions.y / 2 + buttonPosition.top) - popoverDimensions.y / 2
});
break;
case 'left':
popoverEl.css({
left: buttonPosition.left - popoverDimensions.x,
top: (buttonDimensions.y / 2 + buttonPosition.top) - popoverDimensions.y / 2
});
break;
case 'top':
popoverEl.css({
left: buttonPosition.left + (buttonDimensions.x / 2 - popoverDimensions.x / 2),
top: buttonPosition.top - popoverDimensions.y
});
break;
case 'bottom':
popoverEl.css({
left: buttonPosition.left + (buttonDimensions.x / 2 - popoverDimensions.x / 2),
top: buttonPosition.top + buttonDimensions.y
});
break;
}
});
$element.popover(options);
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$element.popover('destroy');
});
return { controlsDescendantBindings: typeof controlDescendants == 'undefined' ? true : controlDescendants };
}
};
var ViewModel = function() {
this.exampleText = ko.observable(" I am trying to close popover on click of out side using knockout binding handler, Please let me know how to do this");
};
ko.applyBindings(new ViewModel());
<body>
<div class="division">
<button data-bind="popover:{template:'settingsPopover',trigger:'click',placement:'bottom'}">settings</button>
</div>
<script type="text/html" id="settingsPopover">
<div data-bind="text: $data.exampleText" type="text"> </div>
</script>
</body>
请为bootstrap 3.3.6建议最好的淘汰捆绑处理程序,并帮助我通过淘汰处理程序点击外侧点击弹出窗口。
答案 0 :(得分:1)
这个插件的棘手之处在于它隐含地附加了按钮的点击事件。它希望该按钮用于切换弹出窗口的可见性,并且不会为您提供任何覆盖它的方法。
控制可见性的更多Knockout方法(当然)是可观察的,当事物可见时为真,否则为假。你可能有:
this.popoverIsOpen = ko.observable(false);
然后在绑定处理程序的update
部分,如
var openControl = ko.unwrap(valueAccessor());
$element.popover(openControl ? 'show' : 'hide');
我为你的小提琴所做的是做一个这样的控制器,然后在主体上放置一个点击装订,总是将它设置为假:
<body data-bind="click: popoverIsOpen.bind($data, false)">
在init
部分,我在显示时将值设置为true,并且我禁用了按钮,因为我要将自己的点击事件发送到正文中的按钮
$element.on('shown.bs.popover', function(event) {
$element.prop('disabled', true);
openControl(true);
我添加了一个订阅,如果新值为false,则重新启用该按钮并通过触发按钮关闭弹出窗口。
openControl.subscribe(function (newValue) {
if (!newValue) {
$element.prop('disabled', false);
$element.click();
}
});
您可以在弹出窗口上放置一个点击装订,以防止其中的点击关闭:
click: function (d,e) {e.stopPropagation();}