用于动态引导工具提示的自定义KnockoutJS绑定处理程序

Custom KnockoutJS bindingHandler for dynamic Bootstrap Tooltips

本文关键字:KnockoutJS 绑定 处理 程序 自定义 动态 工具提示 用于      更新时间:2023-09-26

我在这里发现了一些关于使用带有自定义敲除绑定处理程序的Bootstrap工具提示的其他问题和资源。然而,我还没有发现一个有凝聚力的解决方案,1)涉及使用动态敲除模板2)工具提示可以在绑定的数据发生变化时发生变化。

我也不在GitHub上使用淘汰引导程序,但其中的工具提示标题只呈现一次,

我用以下新的dynamicTooltip创建了一个新的JSFiddle,它是基于以前的JSFiidle的。

新的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
}};

它并不完整,因为我通过在视图Model上传递一个伪数据绑定属性来手动触发更新调用,在这种情况下,它被称为renderTooltip():

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

我希望能够在数据更改时触发工具提示来刷新自己。

我想我应该使用createChildContext()和controlsDescendantBindings,但我真的不确定。

有什么想法吗?我将继续更新这一点,因为动态引导工具提示似乎是一个常见的想法。

问题的根源是更新绑定没有启动,因为它不依赖于您试图更新的属性(即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);

注意:在这两个技巧中,我都对事物进行了一点重构——主要是为了简化