Как инициализировать ViewModel с (частичной) страницы в Durandal/ASP.NET MVC?
-
21-12-2019 - |
Вопрос
у меня есть этот подход (генерация html-файлов из cshtml).
И Стандартная структура каталогов Durandal (ничего особенного).
На некоторых моих страницах(частичный) У меня есть следующее (среди прочего) (SubPage1.cshtml (в Durandal упоминается как «SubPage1.html»)):
...
<select data-bind="event: { change: doSomething }, value: facilityId">
<option value="0">Any Facility</option>
@foreach (var facility in Data.CurrentUserFacilities())
{
<option value="@facility.FacilityId" selected="@CertainCondition">@facility.FacilityName</option>
}
</select>
...
(facilityId
является ko.observable()
в моем коде ViewModel)
Я заполняю данные в зависимости от текущего сеанса пользователя.Это довольно удобно что делать с Бритвой.В этом случае мне не нужно, чтобы данные из раскрывающегося списка были представлены в моей ViewModel Durandal (я имею в виду весь ее список).Однако я нужно, чтобы выбранное значение раскрывающегося списка было применено к ViewModel (SubPage1.js) со страницы (когда страница загружена).
Каков наилучший способ (и если он есть) справиться с этой ситуацией?Я, конечно, понимаю, что в идеале я должен загрузить страницу как статическую (только с привязками Knockout), затем выполнить ajax-запрос к серверу и затем связать загруженные данные.Но а) использование синтаксиса Razor намного удобнее и понятнее;б) это включает в себя дополнительный запрос ajax (и дополнительную серверную логику).
Другой подход, который я вижу, заключается в том, чтобы уведомить ViewModel о том, что страница каким-то образом загружена, и установить (вероятно, вручную через javascript) текущее значение complexId.Нравиться <script type='text/javascript'> myViewModelIgetSomehow.facilityId(45); </script>
.Но это также выглядит не лучшим подходом.
Есть мысли по этому поводу?
На самом деле это скорее вопрос, как справиться с последней упомянутой мыслью (как передать некоторые значения со страницы, загруженной SubPage1.cshtml, в ViewModel SubPage1.js) не только о том, как обращаться с Razor + Durandal ViewModel.
Спасибо!
Решение
Я думаю, что лучшим вариантом было бы создать собственную привязку для нокаута.Вот простой пример:
ko.bindingHandlers["serverCombo"] = {
init: function (element, valueAccessor) {
var $element = $(element);
var options = ko.unwrap(valueAccessor());
var observableTarget = options.value;
$element.change(function onElementChanged() {
var newValue = $element.val();
observableTarget(newValue);
});
},
update: function (element, valueAccessor) {
var $element = $(element);
var options = ko.unwrap(valueAccessor());
var observableTarget = options.value;
$element.val(observableTarget());
}
}
Затем вы можете использовать эту привязку следующим образом:
<select data-bind="serverCombo: { value: facilityId }">
<option value="1">The Deck</option>
<option value="2">The Pool</option>
<option value="3">The Shagpile Carpet and Mirrored Ceiling room</option>
</select>
Вот скрипка, которая объединяет все это воедино.Надеюсь, это поможет!