Gen*_*sky 37 jquery-ui jquery-ui-dialog knockout.js
我正在尝试为jquery ui对话框创建knockoutjs绑定,并且无法打开对话框.对话框元素已正确创建,但似乎没有删除display: none调用dialog('open').此外,调用dialog('isOpen')返回对话框对象而不是布尔值.
我使用最新的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>
Run Code Online (Sandbox Code Playgroud)
这是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);
Run Code Online (Sandbox Code Playgroud)
我已经设置了一个可以重现问题的JSFiddle.
我想知道这是否与knockoutjs和事件处理有关.我尝试true从点击处理程序返回,但似乎没有影响任何东西.
RP *_*yer 64
看起来像是将小部件写入.data("对话框"),然后尝试对其进行操作会导致问题.这是一个.data未使用的示例,并根据元素调用open/close:http: //jsfiddle.net/rniemeyer/durKS/
或者,我喜欢以稍微不同的方式使用对话框.我喜欢使用observable控制对话框是打开还是关闭.因此,您将在对话框本身上使用单个绑定.该init会初始化对话框,同时update将检查可观察到的,看它是否应该调用打开或关闭.现在,打开/关闭按钮只需要切换一个布尔可观察对象,而不是担心id或定位实际对话框.
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");
}
}
};
Run Code Online (Sandbox Code Playgroud)
使用如下:
<div id="dialog" data-bind="dialog: {autoOpen: false, title: 'Dialog test' }, dialogVisible: isOpen">foo dialog</div>
Run Code Online (Sandbox Code Playgroud)
以下是一个示例:http: //jsfiddle.net/rniemeyer/SnPdE/
小智 5
我对RP Niemeyer的回答做了一些改动,允许对话框的选项是可观察的
使用ko.toJS获取observables值以初始化窗口小部件
setTimeout(function() {
options.close = function() {
allBindingsAccessor().dialogVisible(false);
};
$(element).dialog(ko.toJS(options));
}, 0);
Run Code Online (Sandbox Code Playgroud)
并检查更新时的可观察量
//don't call dialog methods before initilization
if (dialog) {
$el.dialog(shouldBeOpen ? "open" : "close");
for (var key in options) {
if (ko.isObservable(options[key])) {
$el.dialog("option", key, options[key]());
}
}
}
Run Code Online (Sandbox Code Playgroud)