KnockOutJS-несколько ViewModels в одном представлении


Я думаю, что мое приложение становится довольно большим сейчас, слишком большим, чтобы обрабатывать каждый вид с помощью одного ViewModel.

поэтому мне интересно, насколько сложно было бы создать несколько ViewModels и загрузить их все в один вид. С заметкой, что я также должен быть в состоянии пройти X ViewModel данные Y ViewModel данные так что отдельные ViewModels должны быть в состоянии общаться друг с другом или по крайней мере быть в курсе каждого другой.

например у меня есть <select> выпадающее меню, что выберите выпадающее меню имеет выбранное состояние, которое позволяет мне передать идентификатор выбранного элемента в <select> к другому вызову Ajax в отдельном ViewModel....

любые точки зрения на работу с многочисленными ViewModels в одном представлении оценены:)

5 193

5 ответов:

если все они должны быть на одной странице, один простой способ сделать это-иметь модель главного представления, содержащую массив (или список свойств) других моделей представления.

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

иначе masterVM может иметь другие свойства, если нужно, для самой страницы. Связь между моделями представления не было бы трудно в этой ситуации, как вы могли бы передать через masterVM, или вы могли бы использовать $parent/$root в привязках, или некоторые другие пользовательские параметры.

нокаут теперь поддерживает несколько привязки модели. Элемент ko.applyBindings() метод принимает необязательный параметр-элемент и его потомки, к которым будет активирована привязка.

например:

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

это ограничивает активацию элементом с ID someElementId и его потомки.

посмотреть документация для более подробной информации.

Это мой ответ после завершения очень большого проекта с большим количеством ViewModels в одном представлении.

Html View

    <!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 модели представления для id=container1 и id=container2 в двух отдельных файлах javascript.

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 viewmodels регистрируются как отдельные viewmodels в 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"));
    }
});

как это вы можете добавить любое количество viewmodels для отдельных дивов. Но убедитесь, что не создавайте отдельную модель представления для div внутри зарегистрированного div.

Проверьте плагин MultiModels для нокаута JS -https://github.com/sergun/Knockout-MultiModels

мы используем компоненты для достижения этой цели. (http://knockoutjs.com/documentation/component-overview.html)

например, у нас есть библиотека компонентов, которую мы разрабатываем:https://github.com/EDMdesigner/knobjs

Если вы покопаетесь в коде, вы увидите, что, например, мы повторно используем компонент ручки-кнопки в нескольких местах.