Twitter bootstrap 3 Modal with knockout

时间:2014-03-28 07:32:33

标签: knockout.js twitter-bootstrap-3

我正在尝试将twitter bootstrap模式与knockout完全绑定。通过完全绑定,我的意思是我希望每次与模态对话的密切交互都能与淘汰赛一起使用。我见过一些questions,它们部分地绑定它们(例如,这个不允许esc)。

我使用几乎相同的绑定(我实际上在其他地方找到了)

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

但问题是,my Fiddle并非一切正常。如果您看到使用“关闭”按钮关闭“模态”,则可以再次触发此模态。但是,如果您使用Esc键或单击背景或X按钮关闭它,则无法再次打开模态。

我知道这个问题是由于当我用其他方式关闭模态时(它没有改变可观察性,因此当我第二次触发它时 - 没有任何变化)。但我无法弄清楚如何正确地做到这一点。

这是我的hack :-),其中一切正常。我每次都给予新的价值。但是有更好的方法吗?

2 个答案:

答案 0 :(得分:43)

bootstrap模式提供了事件,你只需要挂钩事件'hidden.bs.modal'。

顺便说一句,也要妥善处理。 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');
        }
    }
}

答案 1 :(得分:2)

稍微整洁的BS绑定代码 - 并在需要时添加类。:

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

然后只有data-bind="BSModal: true/false Observable"值。