Нокаут - Отменить событие изменения?
У меня есть флажок, привязанный к наблюдаемому на модели представления. У меня есть требование по существу всплыть "Ты уверен?" запрос подтверждения, если пользователь изменяет его с true на false. У меня ужасное время, выясняя лучшее место, чтобы сделать изменение "отмененным".,.
1) Обработчик jQuery для события click
2) Viewmodel internal subscribe "beforeChange"
3) Внутренняя подписка на просмотр (нормальная)
В любом случае, я бы предпочел, чтобы у меня была возможность отменить изменение прямо, чем реагировать на изменение, и, возможно, вернуло его обратно к своему предыдущему значению.
Получает ли событие подписки на нокаут возможность отменить изменение? Любое понимание было бы оценено. Спасибо!
Ответы
Ответ 1
Вот простой вариант с помощью jQuery stopImmediatePropagation:
http://jsfiddle.net/rniemeyer/cBvXM/
<input type="checkbox" data-bind="click: confirmCheck, checked: myvalue" />
JS:
var viewModel = {
myvalue: ko.observable(false),
confirmCheck: function(data, event) {
if (!confirm("Are you sure?")) {
event.stopImmediatePropagation();
return false;
}
return true;
}
};
Ответ 2
Из-за проблем, прокомментированных в ответе @RP Niemeyer, я только что реализовал этот расширитель:
ko.extenders.confirmable = function(target, options) {
var message = options.message;
var unless = options.unless || function() { return false; }
//create a writeable computed observable to intercept writes to our observable
var result = ko.computed({
read: target, //always return the original observables value
write: function(newValue) {
var current = target();
//ask for confirmation unless you don't have
if (unless() || confirm(message)) {
target(newValue);
} else {
target.notifySubscribers(current);
}
}
}).extend({ notify: 'always' });
//return the new computed observable
return result;
};
Затем вы можете применить это к своей модели следующим образом:
var viewModel = {
myvalue: ko.observable(false).extend({confirmable: "Are you sure?"});
}
И если бы был случай, когда вы не требовали подтверждения (в этом глупом примере мы пропустим подтверждение в течение марта), вы можете сделать:
var viewModel = {
myvalue: ko.observable(false).extend({confirmable: { message: "Are you sure?", unless: function() { return new Date().getMonth() == 2 }} });
}