KnockOutJS - Несколько режимов просмотра в одном представлении
Я думаю, что мое приложение становится довольно большим, слишком большим, чтобы обрабатывать каждый вид с помощью одного ViewModel.
Итак, мне интересно, как сложно было бы создать несколько ViewModels и загрузить их все в один вид. С учетом того, что мне также нужно иметь возможность передавать данные X ViewModel в данные Y ViewModel, поэтому отдельные модели ViewModels должны иметь возможность общаться друг с другом или, по крайней мере, знать друг о друге.
Например, у меня есть раскрывающийся список <select>
, который выбирает drop down, имеет выбранное состояние, которое позволяет мне передавать идентификатор выбранного элемента в <select>
на другой вызов Ajax в отдельной ViewModel....
Любые точки при работе с многочисленными ViewModels в одном представлении оцениваются:)
Ответы
Ответ 1
Если все они должны быть на одной странице, один простой способ сделать это - иметь модель основного представления, содержащую массив (или список свойств) других моделей представлений.
masterVM = {
vmA : new VmA(),
vmB : new VmB(),
vmC : new VmC(),
}
Тогда ваш masterVM
может иметь другие свойства, если необходимо, для самой страницы. Связь между моделями просмотра не была бы сложной в этой ситуации, поскольку вы могли бы ретранслировать через masterVM
, или вы могли бы использовать привязки $parent
/$root
в привязке или некоторые другие настраиваемые параметры.
Ответ 2
Нокаут теперь поддерживает множественную привязку модели. Метод ko.applyBindings()
принимает необязательный параметр - элемент и его потомки, к которым будет активирована привязка.
Например:
ko.applyBindings(myViewModel, document.getElementById('someElementId'))
Это ограничивает активацию элемента с идентификатором someElementId
и его потомками.
Подробнее см. documentation.
Ответ 3
Это мой ответ после завершения очень большого проекта с большим количеством 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 режима просмотра регистрируются как отдельные режимы просмотра в 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.
Ответ 4
Проверьте плагин MultiModels для нокаута JS - https://github.com/sergun/Knockout-MultiModels
Ответ 5
Мы используем компоненты для достижения этого. (http://knockoutjs.com/documentation/component-overview.html)
Например, у нас есть эта библиотека компонентов, которую мы разрабатываем: https://github.com/EDMdesigner/knobjs
Если вы вникнете в код, вы увидите, что, например, мы повторно используем компонент кнопки кнопки в нескольких местах.