微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

twitter-bootstrap – Knockout Twitter Bootstrap Popover Binding

我正在尝试为引用模板的twitter boostrap popover创建一个自定义绑定,但是一旦创建了弹出窗口内容的绑定部分我就遇到了问题.

我之前已经看到过这个问题,但我觉得它们大部分都非常混乱,而且我非常接近使用模板的可重用解决方案.

http://jsfiddle.net/billpull/Edptd/

// Bind Twitter Popover
ko.bindingHandlers.popover = {
    init: function(element,valueAccessor,allBindingsAccessor,viewmodel,bindingContext) {
        var tmplId = ko.utils.unwrapObservable(valueAccessor());
        var tmplHtml = $('#' + tmplId).html();
        var uuid = guid();
        var domId = "ko-bs-popover-" + uuid;
        var tmplDom = $('<div/>',{
            "class" : "ko-popover","id" : domId
        }).html(tmplHtml);

        options = {
            content: tmplDom[0].outerHTML
        };

        var popoverOptions = ko.utils.extend(ko.bindingHandlers.popover.options,options);

        console.log($(element));
        console.log(element);

        $(element).bind('click',function () {
            $(this).popover(popoverOptions).popover('toggle');
            ko.applyBindings(bindingContext,document.getElementById(domId));
        });
    },options: {
        placement: "right",title: "",html: true,content: "",trigger: "manual"
    }
};

===编辑

基于下面的答案更新了代码,允许您在没有额外的withProperties绑定的情况下执行此操作

// Bind Twitter Popover
ko.bindingHandlers.popover = {
    init: function(element,bindingContext) {
        // read popover options 
        var popoverBindingValues = ko.utils.unwrapObservable(valueAccessor());

        // 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/>',"id" : domId
        }).html(tmplHtml);

        // set content options
        options = {
            content: tmplDom[0].outerHTML
        };

        // Need to copy this,otherwise all the popups end up with the value of the last item
        var popoverOptions = $.extend({},ko.bindingHandlers.popover.options);
        popoverOptions.content = options.content;

        // bind popover to element click
        $(element).bind(trigger,function () {
            $(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]);
            }
        });

        return { controlsDescendantBindings: true };
    },trigger: "manual"
    }
};

解决方法

你需要用我的老朋友 custom bindings.
ko.bindingHandlers.withProperties = {
    init: function(element,bindingContext) {
        // Make a modified binding context,with a extra properties,and apply it to descendant elements
        var newProperties = valueAccessor(),innerBindingContext = bindingContext.extend(newProperties);
        ko.applyBindingsToDescendants(innerBindingContext,element);

        // Also tell KO *not* to bind the descendants itself,otherwise they will be bound twice
        return { controlsDescendantBindings: true };
    }
};

然后,您需要将data-bind属性添加到您正在生成的html中:

var tmplDom = $('<div/>',{
        "class": "ko-popover","id": domId,"data-bind": "withProperties: { label: '" + viewmodel.label() + "',required: '" + viewmodel.required() + "' }"

我把jsFiddle放在一起显示了这一点.有几个陷阱,我不得不为每个弹出窗口复制弹出框选项,否则它们最终都会得到最后一组值.

var popoverOptions = $.extend({},ko.bindingHandlers.popover.options);
    popoverOptions.content = options.content;

而且我还必须在弹出窗口应用绑定时才显示,否则它似乎试图绑定到整个页面.

$(element).bind('click',function () {
            $(this).popover(popoverOptions).popover('toggle');
            // If you apply this when the popup isn't visible,I think that it tries to bind to thewhole pageand throws an error
            if($('#' + domId).is(':visible'))
            {
                ko.applyBindings(viewmodel,$('#' + domId)[0]);
            }
        });

这似乎也是双向的,因为你可以更改弹出窗口中的值并更新非弹出元素,但我不会说谎,我没想到会发生这种情况!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐