2016-03-11 25 views
2

我是新淘汰賽。我正在使用knockout和bootstrap 3.3.6(最新版本)。我需要通過knockout-bootstrap自定義綁定處理程序關閉引導彈出窗口。我爲bootstrap 3自定義綁定處理程序獲得了一些插件。但是當我點擊正文時我需要關閉popovers。關閉淘汰賽從引導3.3.6點擊外部通過淘汰賽結合處理程序

這是我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> 

請建議最好淘汰賽捆綁處理程序引導3.3.6和幫助我通過淘汰賽處理器,收出上側的點擊酥料餅。

回答

1

這個插件的棘手問題是,它隱式地附加到按鈕的單擊事件。它期望按鈕被用來切換彈出窗口的可見性,並且不會給你任何方式來覆蓋它。

控制可見性的Knockout方法更多(當然),當可見物看起來是真時,否則就是假。你可能有:

this.popoverIsOpen = ko.observable(false); 

,然後在綁定處理類似

var openControl = ko.unwrap(valueAccessor()); 
$element.popover(openControl ? 'show' : 'hide'); 

我做什麼你擺弄的update部分是做一個這樣的控制器,並把點擊綁定身體總是其設置爲false:

<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();} 

Updated fiddle

+0

彈出窗口外點擊工作正常,但彈出窗口身體彈出窗口的點擊不應關閉。你可以更新嗎? – Rayudu