web-dev-qa-db-ja.com

KnockOutJS-単一のビュー内の複数のViewModel

私のアプリケーションは非常に大きくなっており、1つのViewModelで各ビューを処理するには大きすぎると考えています。

したがって、複数のViewModelを作成し、それらすべてを単一のViewにロードすることがどれほど難しいかと思います。 X ViewModel dataをY ViewModel dataに渡すことができる必要があることに注意してください。したがって、個々のViewModelは互いに通信するか、少なくともお互いを認識しています。

たとえば、<select>ドロップダウンがあり、その選択ドロップダウンには<select>の選択されたアイテムのIDを別のViewModelの別のAjax呼び出しに渡すことができる選択状態があります。

単一のビューで多数のViewModelを処理する際のポイントはありがたいです:)

196
CLiown

それらをすべて同じページに配置する必要がある場合、これを行う簡単な方法の1つは、他のビューモデルの配列(またはプロパティリスト)を含むマスタービューモデルを持つことです。

masterVM = {
    vmA : new VmA(),
    vmB : new VmB(),
    vmC : new VmC(),
}

その後、必要に応じて、ページ自体のmasterVMに他のプロパティを設定できます。このような状況では、masterVMを中継したり、バインディングで$parent/$rootを使用したり、その他のカスタムオプションを使用したりできるため、ビューモデル間の通信は難しくありません。

147
John Papa

Knockoutは複数のモデルバインディングをサポートするようになりました。 ko.applyBindings()メソッドは、オプションのパラメーター(バインディングがアクティブになる要素とその子孫)を取ります。

例えば:

ko.applyBindings(myViewModel, document.getElementById('someElementId'))

これにより、ID someElementIdおよびその子孫を持つ要素へのアクティブ化が制限されます。

詳細については documentation をご覧ください。

283
sanatgersappa

これは、単一ビューで多数のViewModelを使用する非常に大規模なプロジェクトを完了した後の私の答えです。

HTMLビュー

    <!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
    <div id="container1">
        <ul>
            <li >Container1 item</li>
            <!-- ko foreach: myItems -->
            <li>Item <span data-bind="text: $data"></span></li>
            <!-- /ko -->
        </ul>
    </div>

    <div id="container2">
        <ul>
            <li >Container2 item</li>
            <!-- ko foreach: myItems -->
                <li>Item <span data-bind="text: $data"></span></li>
            <!-- /ko -->
        </ul>
    </div>

    <script src="js/jquery-1.11.1.js"></script>
    <script src="js/knockout-3.0.0.js"></script>
    <script src="js/DataFunction.js"></script>
    <script src="js/Container1ViewModel.js"></script>
    <script src="js/Container2ViewModel.js"></script>

</body>
</html>

このビューでは、2つの別個のjavascriptファイルにid = container1とid = container2の2つのビューモデルを作成しています。

Container1ViewModel.js

function Container1ViewModel()
{
    var self = this;
    self.myItems = ko.observableArray();
    self.myItems.Push("ABC");
    self.myItems.Push("CDE");

} 

Container2ViewModel.js

function Container2ViewModel() {
    var self = this;
    self.myItems = ko.observableArray();
    self.myItems.Push("XYZ");
    self.myItems.Push("PQR");

}

次に、これら2つのビューモデルがDataFunction.jsの個別のビューモデルとして登録された後

var container1VM;
var container2VM;

$(document).ready(function() {

    if ($.isEmptyObject(container1VM)) {
        container1VM = new Container1ViewModel();
        ko.applyBindings(container1VM, document.getElementById("container1"));
    }

    if ($.isEmptyObject(container2VM)) {
        container2VM = new Container2ViewModel();
        ko.applyBindings(container2VM, document.getElementById("container2"));
    }
});

このように、個別のdivに任意の数のビューモデルを追加できます。ただし、登録済みのdiv内のdivに対して個別のビューモデルを作成しないでください。

21

Knockout JSのMultiModelsプラグインを確認します- https://github.com/sergun/Knockout-MultiModels

3
Sergey Zwezdin

そのためにコンポーネントを使用します。 ( http://knockoutjs.com/documentation/component-overview.html

たとえば、開発中の次のコンポーネントライブラリがあります。 https://github.com/EDMdesigner/knobjs

コードを掘り下げると、たとえば、いくつかの場所でノブボタンコンポーネントを再利用することがわかります。

0
gyula.nemeth