Привязка клика нокаутом с подтверждением JavaScript
Я не могу понять, как создать привязку щелчка для выбивки, которая не выполняет valueAccessor, если диалоговое окно подтверждения JavaScript не вернет true.
Вероятно, это выглядит примерно так:
<a data-bind="confirmClick: { message: 'Are you sure?', click: someMethod }">Confirmable link</a>
Внутри привязка verifyClick будет выглядеть примерно так:
if (confirm(message)) {
click();
}
Я знаю, что смогу обойти это, вставив код confirm(...)
в мой
viewModel, но это не похоже на подходящее место для размещения такого рода кода. Я мог бы также пойти так далеко, чтобы сделать этот вид диалога подтверждения с jQueryUI или Bootstrap, но я хочу кое-что, что я мог бы просто вставить в любой проект.
Я безуспешно отыскивал интернет-сети... Я даже посмотрел исходный код события щелчка для нокаута (https://github.com/knockout/knockout/blob/master/src/binding/defaultBindings/event.js), но он совсем не выглядит дружелюбным...
Любая помощь будет принята с благодарностью!
Ответы
Ответ 1
Вам необходимо создать свой собственный confirmClick
обработчик привязки, который будет обрабатывать ваше сообщение и ваш обработчик кликов и оборачиваться вокруг логики подтверждения:
ko.bindingHandlers.confirmClick = {
init: function(element, valueAccessor, allBindings, viewModel) {
var value = valueAccessor();
var message = ko.unwrap(value.message);
var click = value.click;
ko.applyBindingsToNode(element, { click: function () {
if (confirm(message))
return click.apply(this, Array.prototype.slice.apply(arguments));
}}, viewModel);
}
}
И вы можете это, как вы описали:
<a data-bind="confirmClick: { message: 'Are you sure?', click: someMethod }">
Confirmable link</a>
Демонстрация JSFiddle.
Примечание. Магия click.apply
нужна вам только в том случае, если вы хотите сохранить и передать исходные аргументы обработчика событий click
своему собственному обработчику событий щелчка.
Ответ 2
Я считаю, что именно здесь Knockout определяет обработчик привязки кликов -
ko.bindingHandlers[eventName] = {
'init': function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var newValueAccessor = function () {
var result = {};
result[eventName] = valueAccessor();
return result;
};
return ko.bindingHandlers['event']['init'].call(this, element, newValueAccessor, allBindings, viewModel, bindingContext);
}
}
Где eventName - это "щелчок" для этого обработчика привязки. Я считаю, что размещение этого где-то в вашей модели представления или после загрузки Knockout должно помочь -
ko.bindingHandlers.clickConfirm = {
'init': function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var newValueAccessor = function () {
var result = {};
result.click = function () {
var result = confirm('You are about to confirm something.');
// If they press OK,
console.log('pressed - ', result);
if (result === true) {
console.log('Calling this - ', valueAccessor());
valueAccessor()();
}
}
return result;
};
return ko.bindingHandlers['event']['init'].call(this, element, newValueAccessor, allBindings, viewModel, bindingContext);
}
}
http://jsfiddle.net/XhLKD/