2012-05-14 74 views
12

我有一个复选框绑定到视图模型上的observable。我有一个要求,基本上弹出一个“你确定吗?”确认提示用户是否将其从true更改为false。我有一个可怕的时间找出最好的地方,使变化“可取消”。 。 。淘汰赛 - 取消变更赛事?

1)jQuery的处理程序,单击事件 2)视图模型内部认购“beforeChange” 3)视图模型内部认购(正常)

在任何情况下,我会远远宁愿不得不取消了改变的机会而不是对变化做出反应,如果需要的话,可能会将其恢复到以前的值。

Knockout的订阅事件是否让您有机会取消更改?任何洞察力将不胜感激。谢谢!

回答

22

下面是使用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; 
    } 
}; 
+0

噢,我的天哪!这非常有帮助。我从来不知道jQuery的stopImmediatePropagation()。尽管我通常会尽量避免在核心viewModel之外引用jQuery,但这对我的问题来说是一个很好的解决方案。再次感谢你! – blaster

+2

在我的例子中'event.stopImmediatePropagation'没有停止ko viewModel中改变的值。我不得不再次设置值:var cb = event.target; ... data.myvalue(!cb.checked);' – Sprockincat

+10

在这种情况下,数据绑定的顺序非常重要。如果在事件之前绑定值*,则首先执行值绑定。如果事件被绑定,它将首先执行并停止传播。看到这个小提琴看到它坏了:http://jsfiddle.net/8AuVj/ –

12

由于@RP尼迈耶评论答案的问题的,我只是执行这个扩展器:

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?"}); 
} 

而且,如果有这样的情况,其中不要求确认(在这种无聊的例子中,我们就会在3月期间跳过确认)你可以这样做:

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

太棒了!它可以用在许多场景中。只有一件事,它应该像这样使用:'.extend({confirmable:{message:“Are you sure?”,除非:function(){return new Date()。getMonth()== 2}}}) ;' – Sljux

+0

不错!这是一个精心设计的想法。 –