jquery-ui - 将 jquery ui 对话框与 knockoutjs 集成

标签 jquery-ui jquery-ui-dialog knockout.js

我正在尝试为 jquery ui 对话框创建 knockoutjs 绑定(bind),但无法打开对话框。对话框元素已正确创建,但似乎有 display: none ,调用 dialog('open') 不会删除。此外,对 dialog('isOpen') 的调用返回对话框对象而不是 bool 值。

我正在使用最新的knockoutjs和jquery 1.4.4以及jquery ui 1.8.7。我也用 jQuery 1.7.1 进行了尝试,得到了相同的结果。这是我的 HTML:

<h1 class="header" data-bind="text: label"></h1>

<div id="dialog" data-bind="dialog: {autoOpen: false, title: 'Dialog test'}">foo dialog</div>

<div>
    <button id="openbutton" data-bind="dialogcmd: {id: 'dialog'}" >Open</button>
    <button id="openbutton" data-bind="dialogcmd: {id: 'dialog', cmd: 'close'}" >Close</button>
</div>

这是 JavaScript:

var jQueryWidget = function(element, valueAccessor, name, constructor) {
    var options = ko.utils.unwrapObservable(valueAccessor());
    var $element = $(element);
    var $widget = $element.data(name) || constructor($element, options);
    $element.data(name, $widget);

};

ko.bindingHandlers.dialog = {
        init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
            jQueryWidget(element, valueAccessor, 'dialog', function($element, options) {
                console.log("Creating dialog on "  + $element);
                return $element.dialog(options);
            });
        }        
};

ko.bindingHandlers.dialogcmd = {
        init: function(element, valueAccessor, allBindingsAccessor, viewModel) {          
            $(element).button().click(function() {
                var options = ko.utils.unwrapObservable(valueAccessor());
                var $dialog = $('#' + options.id).data('dialog');
                var isOpen = $dialog.dialog('isOpen');
                console.log("Before command dialog is open: " + isOpen);
                $dialog.dialog(options.cmd || 'open');
                return false;
            });
        }        
};

var viewModel = {
    label: ko.observable('dialog test')
};

ko.applyBindings(viewModel);

我已经设置了JSFiddle重现问题。

我想知道这是否与 knockoutjs 和事件处理有关。我尝试从点击处理程序返回 true,但这似乎没有影响任何内容。

最佳答案

看起来将小部件写入 .data("dialog") 然后尝试对其进行操作会导致问题。以下是一个示例,其中未使用 .data 并根据元素调用打开/关闭: http://jsfiddle.net/rniemeyer/durKS/

或者,我喜欢以稍微不同的方式使用对话框。我喜欢使用可观察对象来控制对话框是打开还是关闭。因此,您可以在对话框本身上使用单个绑定(bind)。 init 将初始化对话框,而 update 将检查可观察对象以查看它是否应该调用打开或关闭。现在,打开/关闭按钮只需要切换 bool 值可观察值,而不用担心 ids 或定位实际的对话框。

ko.bindingHandlers.dialog = {
        init: function(element, valueAccessor, allBindingsAccessor) {
            var options = ko.utils.unwrapObservable(valueAccessor()) || {};
            //do in a setTimeout, so the applyBindings doesn't bind twice from element being copied and moved to bottom
            setTimeout(function() { 
                options.close = function() {
                    allBindingsAccessor().dialogVisible(false);                        
                };

                $(element).dialog(options);          
            }, 0);

            //handle disposal (not strictly necessary in this scenario)
             ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
                 $(element).dialog("destroy");
             });   
        },
        update: function(element, valueAccessor, allBindingsAccessor) {
            var shouldBeOpen = ko.utils.unwrapObservable(allBindingsAccessor().dialogVisible),
                $el = $(element),
                dialog = $el.data("uiDialog") || $el.data("dialog");

            //don't call open/close before initilization
            if (dialog) {
                $el.dialog(shouldBeOpen ? "open" : "close");
            }  
        }
};

用法如下:

<div id="dialog" data-bind="dialog: {autoOpen: false, title: 'Dialog test' }, dialogVisible: isOpen">foo dialog</div>

这是一个示例: http://jsfiddle.net/rniemeyer/SnPdE/

关于jquery-ui - 将 jquery ui 对话框与 knockoutjs 集成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8611327/

相关文章:

jquery ui 对话框在表单加载时缓存

javascript - 基本了解javascript中的函数和声明

javascript - jquery ui Accordion 不自动高度

javascript - 表格排序器不适用于 json

javascript - jquery每次点击事件都一一显示div

jquery - 我怎样才能改变 jQuery UI 对话框的背景

javascript - jQuery 检测是否在 ipad/iphone(移动 safari)上并使用 jQuery 触摸对话框而不是常规的 jquery ui 对话框

javascript - knockout 导致无法解析 foreach 循环中的绑定(bind)属性

javascript - knockout JS 内部和外部绑定(bind)

javascript - jQuery 对话框窗口未居中于页面