【问题标题】:Knockout click binding with javascript confirm使用 javascript 确认敲除点击绑定
【发布时间】:2014-07-17 14:19:06
【问题描述】:

我不知道如何创建不执行 valueAccessor 的敲除点击绑定,除非 javascript 确认对话框返回 true。

大概是这样的:

<a data-bind="confirmClick: { message: 'Are you sure?', click: someMethod }">Confirmable link</a>

在内部,confirmClick 绑定会执行以下操作:

if (confirm(message)) {
   click();
}

我知道我可以通过将 confirm(...) 代码放入我的 viewModel,但这似乎不是放置这种代码的合适位置。我可能还可以使用 jQueryUI 或 Bootstrap 进行这种确认对话框,但我想要一些可以放入任何项目的东西。

我已经在网上搜索了没有运气..我什至查看了淘汰赛点击事件的源代码(https://github.com/knockout/knockout/blob/master/src/binding/defaultBindings/event.js),但它看起来一点也不友好......

任何帮助都将不胜感激!

【问题讨论】:

    标签: javascript knockout.js confirm


    【解决方案1】:

    您需要创建您的自定义 confirmClick binding handler,它接收您的消息和您的点击处理程序并环绕确认逻辑:

    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 事件处理程序参数并将其传递给您自己的单击事件处理程序,则只需要 click.apply 魔法。

    【讨论】:

    • 只是为了完成事情......如果确认返回false,匿名click:function() { ....}应该返回什么?
    • 它将返回undefined,因此 KO 不会调用您的处理程序,也不会执行浏览器操作(单击链接)。但您可以根据需要更改此设置。
    • 在其他答案出现之前已经对此进行了测试,并且效果非常好。我很高兴我花时间研究如何自己做,但我没有接近这种启蒙水平。谢谢!
    • 很好的答案,代码中的小错误。 init 的第三个参数是allBindings 而不是viewModel。您的 JSFiddle 有效,因为您没有在最终方法中使用 vm 参数。
    • 如果你需要在你的点击事件中使用viewModel,你可以将它传递给click.apply函数。像这样:jsfiddle.net/L2Lrjdba/17
    【解决方案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/

    【讨论】:

    • 对工作解决方案表示敬意,但@nemesv 的答案首先出现,有效,至少看起来是一个稍微简单的解决方案。我应该指出,您的两个解决方案中都发生了我无法理解的事情,因此,从技术角度来看,您的答案可能会更好。最终,基于我的无知,我选择了第一个较短的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-15
    • 2018-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多