2016-07-05 3 views
1

私のviewModelには「項目」という配列があります。私はforeachバインディングを使って 'Items'の内容を表示したい。通常のHTMLを使用するとすべて正常に動作します。しかし、jQueryUIを使って作成したダイアログボックスでは動作しません。ノックアウトバインディングjQueryUIダイアログでは機能しません

HTML:

<div id="skus0"> 
    <div id="skus1"> 
    <ul data-bind="foreach: Items"> 
     <li data-bind="text:Name"></li> 
    </ul> 
    </div> 
    <input type="button" id="openQryItems" class="btn btn-info" value="Open" data-bind="click:openQueryItems" /> 
</div> 

はJavaScript:

// my view model 
var viewModel = { 
    Items: [{Name:'Soap'},{Name:'Toothpaste'}] 
}; 

// JS to configure dialogue 
$("#skus1").dialog({ 
    autoOpen: false, 
    width: 500, 
    modal: true, 
    buttons: { 
    "OK": function() { 
     $(this).dialog("close"); 
    }, 
    "Cancel": function() { 
     $(this).dialog("close"); 
    } 
    } 
}); 

// for mapping my model using ko.mapping plugin 
var zub = zub || {}; 
zub.initModel = function (model) { 
    zub.cycleCountModel = ko.mapping.fromJS(model); 
    zub.cycleCountModel.openQueryItems = function() { 
    $("#skus1").dialog("open"); 
    } 
    ko.applyBindings(zub.cycleCountModel, $("#skus0")[0]); 
} 

zub.initModel(viewModel); 

私はここにmy fiddle

+0

@ Matt.kaaj私はko.mappingと名前空間を使用する必要があります。私の実際の世界のモデルは非常に大きく、ko.mappingはそれで私を助けてくれます。 – Harrobbed

答えて

2

$.fn.dialogフィドルを作成しているがDOMでその場所から要素を削除し、新しい容器にそれを置きます;これは浮動ウィンドウを作成する方法です。この問題の問題は、ダイアログDOMがトップレベルのデータバインドDOM内にネストされていないため、データバインディングが中断されることです。

ko.applyBindingsにダイアログの初期化を移動すると、リストが移入され後DOM 外のものをヤンクするdialogを可能にします。もちろん、これ以降は、将来の変更はまだ反映されません。これは、開いているダイアログを自動的に変更したい場合に重要です。

ダイアログの内容を完全に動的にしたい場合は、バインディングハンドラを作成できます。プロジェクトでこれを行いました。あるん何return { controlsDescendantBindings: true }

<div data-bind="dialog: { title: 'some title', id: 'foo', ... }"> 
    <!-- dialog contents --> 
</div> 

は外バインディングがバインディングdialogを使用して、何も影響はありませんことを確認します:私たちはこのように使用

ko.bindingHandlers.dialog = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingCtx) { 
    var bindingValues = valueAccessor(); 
    var hasAppliedBindings = false; 
    var elem = $(element); 
    var options = { 
     id: ko.utils.unwrapObservable(bindingValues.id), 
     title: ko.utils.unwrapObservable(bindingValues.title), 
     // etc... 
     onOpen: function() { 
     if (!hasAppliedBindings) { 
      hasAppliedBindings = true; 
      var childCtx = bindingCtx.createChildContext(viewModel); 
      ko.applyBindingsToDescendants(childCtx, element); 
     } 
     } 
    }; 

    elem.dialog(options); 
    } 

    return { controlsDescendantBindings: true }; 
} 

...:ここでは、これをしなかったかの大まかな概要ですハンドラ。その後、元のビューモデルに基づいて、DOMから引き出された後に独自のノックアウトバインディング "島"を作成します。

私たちのプロジェクトでは、ハイブリッドjQuery + Knockoutも使用していましたが、できる限りこれを避けることを強くお勧めします。このタイプのアプリケーションを維持するためには、非常に多くのハッキングがありました。 UI管理のバグを避けるために、ノックアウトバインディングハンドラを好むのが最も良い方法です(そして、これは私がこれまで使っていない "コンポーネント"のコンセプトを持っています)。

+0

ありがとう!家に帰ってそれを試した。それは働いた。私がしなければならなかったのは、あなたが提案したようにko.applyBindingsの後にダイアログを初期化することでした。 – Harrobbed

関連する問題