Twitter bootstrap 3 Modal with knockout

旧时模样 提交于 2019-12-28 02:51:11

问题


I am trying to fully bind twitter bootstrap modal with knockout. By fully bind I mean that I want every close interaction with modal dialog to work with knockout. I have seen some of the questions, which partially bind them (for example this one does not allow esc).

I am using almost identical binding (which I actually found elsewhere)

ko.bindingHandlers.modal = {
    init: function (element, valueAccessor) {
        $(element).modal({
            show: false
        });
    },
    update: function (element, valueAccessor) {
        var value = valueAccessor();
        if (ko.utils.unwrapObservable(value)) {
            $(element).modal('show');
        } else {
            $(element).modal('hide');
        }
    }
}

But the problem is that not everything work in my Fiddle. As you see if you close Modal with Close button, you can fire this modal again. But if you close it with Esc key, or with clicking on background, or on the X button, you can not open Modal again.

I know that the problem is due to the fact that when I close modal with other means (it is not changing observable and therefore when I fire it for the second time - nothing changes). But I can not figure out how to do this properly.

Here is my hack :-), where everything works. I am giving new value each time. But is there a better way?


回答1:


bootstrap modal provided events, you just need to hook up event 'hidden.bs.modal'.

BTW, do proper disposal too. http://jsfiddle.net/C8w8v/377/

ko.bindingHandlers.modal = {
    init: function (element, valueAccessor) {
        $(element).modal({
            show: false
        });

        var value = valueAccessor();
        if (ko.isObservable(value)) {
            // Update 28/02/2018
            // Thank @HeyJude for fixing a bug on
            // double "hide.bs.modal" event firing.
            // Use "hidden.bs.modal" event to avoid
            // bootstrap running internal modal.hide() twice.
            $(element).on('hidden.bs.modal', function() {
               value(false);
            });
        }

        // Update 13/07/2016
        // based on @Richard's finding,
        // don't need to destroy modal explicitly in latest bootstrap.
        // modal('destroy') doesn't exist in latest bootstrap.
        // ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
        //    $(element).modal("destroy");
        // });

    },
    update: function (element, valueAccessor) {
        var value = valueAccessor();
        if (ko.utils.unwrapObservable(value)) {
            $(element).modal('show');
        } else {
            $(element).modal('hide');
        }
    }
}



回答2:


slightly neater BS binding code - and classes are added when needed.:

ko.bindingHandlers.BSModal= {
    init: function (element, valueAccessor) {
        var value = valueAccessor();
        $(element).addClass('modal').addClass('fade').modal({ keyboard: false, show: ko.unwrap(value) });;
    },
    update: function (element, valueAccessor) {
         var value = valueAccessor();
         ko.unwrap(value) ? $(element).modal('show') : $(element).modal('hide');
    }
};

Then just data-bind="BSModal: true/false Observable" value.



来源:https://stackoverflow.com/questions/22706765/twitter-bootstrap-3-modal-with-knockout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!