KnockOutJS - несколько ViewModels в одном представлении - PullRequest
197 голосов
/ 15 февраля 2012

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

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

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

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

Ответы [ 5 ]

284 голосов
/ 20 июля 2012

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

Например:

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

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

Подробнее см. документация .

148 голосов
/ 15 февраля 2012

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

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

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

21 голосов
/ 16 июля 2014

Это мой ответ после завершения очень большого проекта с множеством 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 в 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 внутри зарегистрированного div.

3 голосов
/ 27 июня 2012

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

0 голосов
/ 28 июня 2016

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

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

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

...