2013-02-12 31 views
2

我已創建自定義爲敲除用於Twitter的引導popovers結合和我使用與在酥料餅的雙向結合顯示的數據,但是如果內容的大小是每個酥料餅之間不同排列是關閉Twitter的引導Popovers未對齊具有不同尺寸的內容

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">&nbsp;</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/

回答

0

DEMO

可能是你可以使用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');   
    // } 
}); 
0

當您綁定點擊元素在你的酥料餅的結合,你初始化引導酥料餅,然後appply結合的後代。這就是爲什麼bootstrap popover不正確地計算它的位置(沒有嵌套的li-s,所以它們的高度爲零)。在這之後,淘汰賽會添加li-s元素和popover高度更改,並且您必須重新計算popover位置。

下一個後,點擊重新初始化引導酥料餅,但不應用綁定,這種情況下酥料餅的位置,正確地計算。

+0

你能想出反正,因爲我不知道我是否可以在popover創建之前應用綁定 – BillPull 2013-02-13 19:20:58

+0

不幸的是,bootstrap和knockout有點不兼容,目前引導程序用html代碼替換popover內容在打開的時候,這是敲除綁定丟失的地方,另外open方法包含了位置計算,這就是爲什麼在popover.open和knockout綁定應用後你不能單獨重新計算它,所以我建議重寫bootstrap popover - 的位置計算,並在應用敲除綁定後運行它或... – Kasheftin 2013-02-14 11:29:36

+0

...更改彈出窗口的邏輯,以便打開和隱藏方法僅更改彈出窗口內容的可見性而不影響dom結構 – Kasheftin 2013-02-14 11:30:15

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');   
// } 
}); 

的酥料餅永遠不會關閉出於某種原因! :(