0

問題のビデオデモ:http ://www.screenr.com/k168

  • 「y」ボタンをクリックして、サーバーからデータを取得します。
  • 最初の結果の「詳細を表示」リンク(y-cof-dmx)をクリックして、レコードの詳細ビューを表示します。薬剤名をメモします(モーダルタイトルバー/データテーブルとコンソールの両方にあります)。それらはすべて一致します。ここまでは順調ですね。
  • 次の結果の「詳細を表示」リンク(Yasmin 28)をクリックします。モーダルとコンソールの薬剤名に注意してください。コンソールは現在のモデルオブジェクトを認識していますが、モーダルは更新されません。それでも「古い」結果、y-cof-dmxです。
  • 次の結果( Yaz )についても同じことが言えますが、モーダルでは「古い」結果が表示されます。
  • モーダルで薬剤名を編集します。UI全体で更新され、モーダルを再度開いたときに反映されます。

私のオブザーバブルは常に更新されていますが、常に更新されているわけではありません。なぜなのかわかりません。

私のコードはすべて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');
};

showDetailsの上のほんの一握りの行で宣言されているobservableを更新しようとしているところ:

selectedItem: ko.observable(),

私が扱っているデータは単純なオブジェクトです。構造はJavaScriptペインの上部( http://jsfiddle.net/Gm64C/2/ )に表示されます(他のすべては無視してください)。

どんな洞察も大歓迎です!


以下の私の最初のコメントからの更新

これが私の改訂の適切な部分です。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()}">

jqueryUIダイアログの新しいカスタム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');
}
};
4

1 に答える 1

0

あなたの問題はおそらくjQueryダイアログとknockout.jsの組み合わせです。jQueryがダイアログを作成するとき、DOMツリーに対して操作を実行します。これらの操作は、DOMツリーでも操作するKnockout.jsと競合する場合と競合しない場合があります。jsFiddleが機能していないと、これを確認するのは困難ですが、問題はそこにあると思います。

jQueryダイアログをラップアラウンドするカスタムKnockout.jsバインディングをすでに使用しているようです。バインディングを、この質問で受け入れられた回答のバインディングに置き換えてみてください。

jqueryuiダイアログをknockoutjsと統合する

于 2012-09-06T07:55:27.663 に答える