web-dev-qa-db-fra.com

KnockOutJS - Plusieurs ViewModels dans une seule vue

Je pense que mon application est en train de devenir assez volumineuse, trop grande pour gérer chaque vue avec un seul ViewModel.

Je me demande donc à quel point il serait difficile de créer plusieurs ViewModels et de tous les charger dans une seule vue. Avec une note que je dois également pouvoir transmettre X ViewModel données en Y ViewModel données, les différents ViewModels doivent pouvoir communiquer entre eux ou au moins être conscient de l'autre.

Par exemple, j'ai un menu déroulant <select>, ce qui sélectionne un état sélectionné qui me permet de transmettre l'ID de l'élément sélectionné dans le <select> à un autre appel Ajax dans un ViewModel séparé ... .

Tous les points sur le traitement de nombreux ViewModels dans une seule vue appréciée :)

198
CLiown

S'ils doivent tous se trouver sur la même page, une méthode simple consiste à utiliser un modèle de vue principal contenant un tableau (ou une liste de propriétés) des autres modèles de vue.

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

Ensuite, votre masterVM peut avoir d’autres propriétés si nécessaire, pour la page elle-même. La communication entre les modèles de vue ne serait pas difficile dans cette situation, car vous pouvez relayer via masterVM, ou vous pouvez utiliser le $parent/$root dans les liaisons ou d'autres options personnalisées.

148
John Papa

Knockout prend désormais en charge la liaison de plusieurs modèles. La méthode ko.applyBindings() prend un paramètre facultatif - l'élément et ses descendants pour lesquels la liaison sera activée.

Par exemple:

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

Cela limite l'activation à l'élément portant l'ID someElementId et ses descendants.

Voir documentation pour plus de détails.

284
sanatgersappa

Voici ma réponse après avoir terminé un très grand projet avec beaucoup de ViewModels en vue unique.

Html Voir

    <!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>

Pour cette vue, je crée deux modèles de vues pour id = conteneur1 et id = conteneur2 dans deux fichiers javascript distincts.

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");

}

Ensuite, après ces 2 modèles de vue, enregistrez-vous en tant que modèles de vue distincts dans 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"));
    }
});

Comme cela, vous pouvez ajouter un nombre quelconque de modèles de vue pour des divs distincts. Mais assurez-vous de ne pas créer de modèle de vue distinct pour une div dans une div enregistrée.

21
Janith Widarshana

Vérifiez le plugin MultiModels pour Knockout JS - https://github.com/sergun/Knockout-MultiModels

3
Sergey Zwezdin

Nous utilisons des composants pour y parvenir. ( http://knockoutjs.com/documentation/component-overview.html )

Par exemple, nous développons cette bibliothèque de composants: https://github.com/EDMdesigner/knobjs

Si vous creusez dans le code, vous verrez que, par exemple, nous réutilisons le composant bouton-poussoir à plusieurs endroits.

0
gyula.nemeth