淘汰赛 - 取消变更赛事?

bla*_*ter 12 jquery mvvm knockout.js

我有一个绑定到视图模型上的observable的复选框.我要求基本上弹出一个"你确定吗?" 如果用户将其从true更改为false,则显示确认提示.我有一个可怕的时间找出使变化"可取消"的最佳位置...

1)点击事件的jQuery处理程序2)Viewmodel内部订阅"beforeChange"3)Viewmodel内部订阅(正常)

在任何情况下,我都非常希望有机会直接取消更改,而不是对更改作出反应,如果需要,可能会将其恢复为之前的值.

Knockout的订阅活动是否让您有机会取消更改?任何见解将不胜感激.谢谢!

RP *_*yer 22

这是一个使用jQuery的stopImmediatePropagation的简单选项:

http://jsfiddle.net/rniemeyer/cBvXM/

<input type="checkbox" data-bind="click: confirmCheck, checked: myvalue" />
Run Code Online (Sandbox Code Playgroud)

JS:

var viewModel = {
    myvalue: ko.observable(false),
    confirmCheck: function(data, event) {
        if (!confirm("Are you sure?")) {
            event.stopImmediatePropagation();            
            return false;
        }
        return true;
    }
};
Run Code Online (Sandbox Code Playgroud)

  • 在这种情况下,数据绑定的顺序非常重要.如果在*事件之前绑定值*,则首先执行值绑定.如果事件被绑定,它将首先执行并停止传播.看到这个小提琴看到它坏了:http://jsfiddle.net/8AuVj/ (11认同)
  • 在我的情况下,`event.stopImmediatePropagation`没有停止在ko viewModel中更改值.我不得不再次设置值:`var cb = event.target; ... data.myvalue(!cb.checked);` (2认同)
  • @Jimmy Bosse - 这是值得的答案,正是我遇到的问题. (2认同)

mga*_*aia 13

由于@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;
};
Run Code Online (Sandbox Code Playgroud)

然后,您可以将其应用于您的模型,如下所示:

var viewModel = {
    myvalue: ko.observable(false).extend({confirmable: "Are you sure?"});
}
Run Code Online (Sandbox Code Playgroud)

而且,如果有一个案例不要求确认(在这个愚蠢的例子中,我们将在3月份跳过确认),你可以这样做:

var viewModel = {
    myvalue: ko.observable(false).extend({confirmable: { message: "Are you sure?", unless: function() { return new Date().getMonth() == 2 }} });
}
Run Code Online (Sandbox Code Playgroud)