Мне нужно получить как текущее значение, так и доступные параметры <select />
через два разных вызова AJAX (я не могу поставить их в очередь/связать по нескольким причинам).
Я не знаю, имеет ли это значение, но вызов, читающий текущее значение, каждый раз завершается до того, как вызов считывает доступные параметры.
Используя Knockout 2.0.0 и Knockout Mapping 2.0.3, я связал выбор с data-bind="options: values, value: valueComputed"
, но обнаружил, что Knockout удаляет/игнорирует значение, установленное первым вызовом AJAX, до тех пор, пока не завершится вызов, извлекающий доступные параметры, невозможно установить текущее значение.
Это правильно? Можно ли сказать Knockout «это текущее значение, когда станут доступны доступные параметры, выберите его»?
После пары тестов я придумал кладж: вместо привязки простого наблюдаемого к значению выбора я использовал вычисляемый наблюдаемый, где я перехватываю значение и не изменяю базовый наблюдаемый, если новое значение не определено.
Я делаю что-то злое?
Пример jsFiddle: http://jsfiddle.net/KeNUU/
Код JavaScript, который я использую:
var viewModel = function () {
var self = this;
// The underlying observable where
// the selected value is stored.
self.value = ko.observable();
// The observable bound to
// the value of the drop down.
self.values = ko.mapping.fromJS([]);
// Use a computed observable to intercept the undefined
// value placed by KnockOut when binding the drop down.
self.valueComputed = ko.computed({
"read": function () {
return ko.utils.unwrapObservable(self.value);
},
"write": function (value) {
// Update the underlying observable only when
// there is a value, if it's undefined ignore it.
if (value) {
self.value(value);
}
}
});
// Simulate the AJAX request which fetches the actual value,
// this request must complete before the second one.
setTimeout(function () {
self.valueComputed("b");
}, 1000 * 1);
// Simulate the AJAX request which fetches the available values,
// this reqest must complete after the first one.
setTimeout(function () {
ko.mapping.fromJS(["a", "b", "c", "d"], {}, self.values);
}, 1000 * 2);
};
$(document).ready(function () {
ko.applyBindings(new viewModel());
});