Knockout observable并不总是更新(视频链接内)

时间:2012-09-05 22:39:55

标签: knockout.js knockout-mapping-plugin observable

问题的视频演示:http://www.screenr.com/k168

  • 我点击“y”按钮从服务器获取一些数据。
  • 我点击第一个结果的“显示详细信息”链接( y-cof-dmx )来显示记录详细信息视图 - 记下药物名称(两者都在模态标题栏/数据表中在控制台中)。他们都匹配。到目前为止,这么好。
  • 点击下一个结果的“显示详细信息”链接( Yasmin 28 )。注意模态和控制台中的药物名称。控制台知道当前的模型对象,但模态没有得到更新,它仍然是“旧的”结果, y-cof-dmx
  • 下一个结果( Yaz )也是如此,仍然会在模态中显示“旧”结果。
  • 我在模态中编辑药物名称 - 它在整个用户界面中得到更新,并在我再次弹出模式时反映出来。

我的观察结果正在变化,而不是所有时间。我不确定为什么会这样。

我的所有代码都在http://jsfiddle.net/6fm5T/,尽管它不会在小提琴中运行。

代码的有趣部分,可以找到模态:

<!-- start modal: drug details -->
<div data-bind="with: selectedItem">

在JS中,有:

//show details in modal
viewModel.showDetails = function(obj) {
    //add/update currently selected drug
    viewModel.selectedItem(obj);

    console.log(viewModel.selectedItem().drugName());

    //show modal dialog
    $('#dialog').dialog('open');
};

我试图更新observable,它只是在showDetails上面的一些行声明:

selectedItem: ko.observable(),

我正在处理的数据是简单的对象,可以在http://jsfiddle.net/Gm64C/2/的JavaScript窗格顶部看到该结构(忽略其他所有内容)。

非常感谢任何见解!


我的第一次评论更新

以下是我的修订版的相关部分。在html中,我不得不将drugName作为函数调用:

由此:

<!-- start modal: drug details -->
<div data-bind="with: selectedItem">
    <div id="dialog" data-bind="jqDialog: {title: drugName}">

对此:

<!-- start modal: drug details -->
<div data-bind="with: selectedItem">
    <div id="dialog" data-bind="jqDialog: {title: drugName()}">

这是我为jquery UI对话框新的自定义KO绑定:

由此:

ko.bindingHandlers.jqDialog = {
init: function(element) {
    //console.log('jqDialog init');
    ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
        $(element).dialog('destroy');
    });

    //setup modal dialog options - details view
    $('#dialog').dialog({
        autoOpen: false,
        closeOnEscape: true,
        modal: true,
        width: 850,
        height: 500
    });
},
update: function(element, valueAccessor) {
    //console.log('jqDialog update');
    var options = ko.toJS(valueAccessor());

    //console.log(options);

    if (options) {
        //console.log('jqUpdate options');
        $(element).dialog(options);
    }            
}
};

对此:

ko.bindingHandlers.jqDialog = {
    init: function(element, valueAccessor) {
    var options = ko.utils.unwrapObservable(valueAccessor()),
        modalDefaults = {
        autoOpen: 'false',
        closeOnEscape: 'true',
        modal: 'true',
        width: '850',
        height: '500'
    };

    $.extend(options, modalDefaults);

    setTimeout(function() { 
        $(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);
     $(element).dialog(shouldBeOpen ? 'open' : 'close');
}
};

1 个答案:

答案 0 :(得分:0)

你的问题可能是 jQuery对话框和knockout.js的组合。当jQuery创建一个对话框时,它会对DOM树执行操作。这些操作可能会或可能不会与Knockout.js冲突,后者也在DOM树上运行。没有工作的jsFiddle,我很难确认这一点,但我的猜测是你的问题就在那里。

我看到你已经使用了一个包装jQuery对话框的自定义Knockout.js绑定。尝试用这个问题的接受答案替换绑定:

integrating jquery ui dialog with knockoutjs