2013-12-13 65 views
0

我發現了一些其他問題和資源在這裏使用Bootstrap工具提示與自定義挖空綁定處理程序。然而,我還沒有發現是一個有凝聚力的解決方案,1)涉及使用動態挖空模板2)其中工具提示可以在數據發生變化時改變的解決方案。自定義KnockoutJS bindingHandler動態引導工具提示

我也走的knockout-bootstrap在GitHub上,但在工具提示標題渲染一次,

我已經創建了一個新JSFiddle與同時基於現有JSFiddle以下新dynamicTooltip。

新DynamicTooltip數據綁定的樣子:

ko.renderTemplateHtml = function (templateId, data) { 
    var node = $("<div />")[0]; 
    ko.renderTemplate(templateId, data, {}, node); 
    return $(node).html(); 
}; 

ko.bindingHandlers.tooltip = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
    var local = ko.utils.unwrapObservable(valueAccessor()), 
     options = {}; 

    ko.utils.extend(options, ko.bindingHandlers.tooltip.options); 
    ko.utils.extend(options, local); 

    var tmplId = options.kotemplate; 

    ko.utils.extend(options, { 
     title: ko.renderTemplateHtml(tmplId, viewModel) 
    }); 

    $(element).tooltip(options); 

    ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
     $(element).tooltip("destroy"); 
    }); 
}, 
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
    var local = ko.utils.unwrapObservable(valueAccessor()), 
     options = {}; 

    ko.utils.extend(options, ko.bindingHandlers.tooltip.options); 
    ko.utils.extend(options, local); 

    var tmplId = options.kotemplate; 
    var forceRefresh = options.forceRefresh; 
    var newdata = ko.renderTemplateHtml(tmplId, viewModel); 
    $(element).data('bs.tooltip').options.title = newdata 

}, 
options: { 
    placement: "top", 
    trigger: "hover", 
    html: true 
}}; 

這是不完全的,因爲我手動手動觸發更新調用通過傳遞虛擬數據綁定屬性的視圖模式,在這種情況下,它的調用renderTooltip():

<a data-bind="tooltip: { title: firstName, placement: 'bottom', kotemplate: 'tile-tooltip-template', forceRefresh: renderTooltip() }">Hover on me</a> 

我希望能夠觸發工具提示以在數據更改時自行刷新。

我在想我應該使用createChildContext(),也許controlsDescendantBindings,但我不太確定。

有什麼想法?我將繼續更新它,因爲它似乎像動態引導工具提示是一個常見的想法。

回答

1

問題的根源在於更新綁定不會觸發,因爲它沒有依賴於您要更新的屬性(即firstName和address);

通常,您可以將這些屬性委託給新的綁定,並讓knockout自動處理依賴關係跟蹤。但是,在這種情況下,您實際上正在返回一個字符串,因此該元素的自動綁定無法使用。字符串是必要的,因爲這是工具提示的工作方式。如果它可以動態地從DOM元素讀取,那麼自動綁定就可以工作,但是因爲它需要一個HTML字符串,所以綁定無法影響這個綁定。

情侶的,我看到的選項:

1.自動創建模板使用性能的依賴。這可以通過隔離所看到在這個小提琴模板視圖模型(數據)來完成:http://jsfiddle.net/tMbs5/13/

//create a dependency for each observable property in the data object 
for(var prop in templateData) 
    if(templateData.hasOwnProperty(prop) && ko.isObservable(templateData[prop])) 
     templateData[prop](); 

2而不是使用基於DOM的模板,使用ko.computed產生內模板您查看模型。這將根據需要自動創建依賴關係。 http://jsfiddle.net/tMbs5/12/

var vm = { 
    firstName: ko.observable('Initial Name'), 
    address: ko.observable('55 Walnut Street, #3'), 
    changeTooltip: function() { 
     this.firstName('New Name'); 
    } 
}; 

vm.tooltipHtml = ko.computed(function() { 
    return "<h2>" + vm.firstName() + "</h2>" + 
     "<span>" + vm.address() + "</span>"; 
}); 

ko.applyBindings(vm); 

注: 用於這方面的一個例子來看看這個小提琴在這兩個小提琴,我已經重構的東西一點點 - 主要是爲了簡化

+0

謝謝,我喜歡V1好一點,因爲我是想保持DOM不在虛擬機中。特別是因爲我真實的例子,沒有減少到firstName和地址屬性是相當大的。 – taudep

+0

我想廣告宣傳,您的解決方案跟蹤屬性是很好的。我試圖從自定義bindingHandler中做類似的事情,但被卡住了。 – taudep

+0

我有一個新的JSFiddle:http://jsfiddle.net/tMbs5/14/,這將顯示名稱可以在連續的數據綁定操作中實際更改。 – taudep