У меня есть элемент управления, связанный с наблюдаемым массивом Knockout:
<select data-bind="event: { change: selectedProductOfferingChange }, options: $parent.productTypes, optionsText: 'text', optionsCaption: '-- Select --', value: selectedProductType, enable: !isReadOnly()"></select>
Когда выбор изменен, я хочу запустить некоторый код, возможно, сделать вызов AJAX. Если изменение не разрешено, я хочу отменить изменение и отобразить модальное диалоговое окно. Я не могу подписаться на свойство, поскольку оно будет срабатывать после изменения. Мне нужно новое значение, чтобы определить, нужно ли отменять изменение или нет.
Я попробовал следующее в viewmodel, но изменение не отменено, хотя свойство (selectedProductOffering) на viewmodel не обновляется:
self.selectedProductOfferingChange = function (data, event) {
event.stopImmediatePropagation();
return false;
};
Могу ли я использовать опцию "beforeChange" с подпиской?
self.selectedProductType.subscribe(function (previous) {
}, self, "beforeChange");
Могут ли изменения быть отменены здесь?
Подумав, вот что я придумал:
self.selectedProductOfferingChange = function (data, e) {
// Do any checking here
if (confirm("OK to make this change ?")) { return; }
// This stops the viewmodel property from being updated
e.stopImmediatePropagation();
// Since the viewmodel property hasn't changed, force the view to update
self.selectedProductType.valueHasMutated();
};
Проблема с этим кодом заключается в том, что он не дает вам доступ к новому значению. Вычисленный вариант позволит решить эту проблему:
<select data-bind="options: $parent.productTypes, optionsText: 'text', optionsCaption: '-- Select --', value: computedSelectedProductType, enable: !isReadOnly()"></select>
self.computedSelectedProductType = ko.computed({
read: function () {
return self.selectedProductType();
},
write: function (value) {
// Do any checks here. If you want to revert to the previous
// value, don't call the following but do call:
// self.selectedProductType.valueHasMutated()
self.selectedProductType(value);
},
owner: self
});