webentwicklung-frage-antwort-db.com.de

KnockOutJS - Mehrere ViewModels in einer Ansicht

Ich denke, dass meine Anwendung jetzt ziemlich groß wird, zu groß, um jede Ansicht mit einem einzelnen ViewModel zu verarbeiten.

Ich frage mich also, wie schwierig es wäre, mehrere ViewModels zu erstellen und sie alle in eine einzige View zu laden. Mit einem Hinweis, dass ich auch in der Lage sein muss, X ViewModel Daten in Y ViewModel Daten zu übertragen, damit die einzelnen ViewModels miteinander kommunizieren können oder zumindest in der Lage sein müssen sich bewusst sein.

Zum Beispiel habe ich ein <select> Dropdown, dieses Dropdown-Auswahlfeld hat einen ausgewählten Status, der es mir ermöglicht, die ID des ausgewählten Elements im <select> zu einem anderen Ajax-Aufruf in einem separaten ViewModel ....

Irgendwelche Punkte zum Umgang mit zahlreichen ViewModels in einer einzigen Ansicht sind erwünscht :)

198
CLiown

Wenn sich alle Elemente auf derselben Seite befinden müssen, besteht eine einfache Möglichkeit darin, ein Master-Ansichtsmodell zu erstellen, das ein Array (oder eine Eigenschaftsliste) der anderen Ansichtsmodelle enthält.

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

Dann kann Ihr masterVM bei Bedarf andere Eigenschaften für die Seite selbst haben. Die Kommunikation zwischen den Ansichtsmodellen wäre in dieser Situation nicht schwierig, da Sie die Weiterleitung über masterVM oder die $parent/$root in Bindungen oder einigen anderen benutzerdefinierten Optionen.

148
John Papa

Knockout unterstützt jetzt die Bindung mehrerer Modelle. Die ko.applyBindings() -Methode akzeptiert einen optionalen Parameter - das Element und seine Nachkommen, für das die Bindung aktiviert wird.

Beispielsweise:

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

Dies beschränkt die Aktivierung auf das Element mit der ID someElementId und seinen Nachkommen.

Siehe Dokumentation für weitere Details.

284
sanatgersappa

Dies ist meine Antwort nach Abschluss eines sehr großen Projekts mit vielen ViewModels in der Einzelansicht.

HTML-Ansicht

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

Für diese Ansicht erstelle ich zwei Ansichtsmodelle für id = container1 und id = container2 in zwei separaten Javascript-Dateien.

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

}

Danach registrieren sich diese beiden Ansichtsmodelle als separate Ansichtsmodelle in 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"));
    }
});

Auf diese Weise können Sie eine beliebige Anzahl von Ansichtsmodellen für separate Divs hinzufügen. Aber stellen Sie sicher, dass Sie kein separates Ansichtsmodell für ein Div innerhalb eines registrierten Div erstellen.

21

Überprüfen Sie das MultiModels-Plugin auf Knockout JS - https://github.com/sergun/Knockout-MultiModels

3
Sergey Zwezdin

Dafür setzen wir Komponenten ein. ( http://knockoutjs.com/documentation/component-overview.html )

Zum Beispiel haben wir diese Komponentenbibliothek, die wir entwickeln: https://github.com/EDMdesigner/knobjs

Wenn Sie in den Code eintauchen, werden Sie feststellen, dass wir beispielsweise die Knopf-Knopf-Komponente an mehreren Stellen wiederverwenden.

0
gyula.nemeth