2012-04-11 72 views
4

我无法弄清楚如何在与绑定click相关联的方法中访问已通过checked绑定更新的值?Knockoutjs:同时使用点击和检查绑定时绑定评估的顺序

似乎checked结合求值AFTER click结合,因为在click装订方法/处理程序无法访问其取决于阵列checked结合同步computed属性值。

模板单个复选框:视图模型的

<script id="singleFilterTemplate" type="text/html"> 
    <li> 
     <input type="checkbox" data-bind="attr: { value: id }, 
              click: $root.testMethod, 
              checked: $parent.selectedFilterIds"> 
    </li> 
</script> 

我下面的层级:

- TopLevelViewModel ($root in template above, defines computed aggregatedSelectedIds property) 
---- GroupViewModel_0 ($parent in template above) 
-------FilterViewModel_0_0 (Each FilterViewModel is associated with a check box) 
-------FilterViewModel_0_N 
---- GroupViewModel_N 
-------FilterViewModel_N_0 
-------FilterViewModel_N_N 
  • checked: $parent.selectedFilterIds:每次复选框被选中/取消 - 选择合适的选项在TopLevelViewModel.selectedFilterIds阵列更新
  • click: $root.testMethod:虽然点击复选框,我试图抓住所有复选框的当前状态,为此,我已经引入了计算属性aggregatedSelectedIds,它运行良好,并代表所有GroupViewModel.selectedFilterIds值的聚合状态,基本上它将来自所有selectedFilterIds属性的元数据聚合为单个值,并且在testMethod()中, m只需拨打alert(topLevelViewModel.aggregatedSelectedIds())即可确保此属性表示当前选定的过滤器列表。

因此,每个由click调用时testMethod()结合 - 我看到了过滤器的先前状态(值,由aggregatedSelectedIds计算)。那么有什么办法在click绑定之前强制/推送/评估checked绑定?我试过event绑定,但得到了相同的结果。也许我以错误的方式做了这件事,错过了一些明显的东西?

回答

4

您可以通过执行

this.selectedFilterIds = ko.observable(); 
this.selectedFilterIds.subscribe(function (value) { 
    //Code from your click method goes here 
}); 
+0

为我工作!非常感谢 :) – 2012-05-23 16:21:07

0

通常情况下,方法绑定和执行的顺序,你很好..绑定他们..看起来像你绑定首先点击。不知道knockoutjs如何处理这个,虽然从数据绑定attr?

例如

$(this).click(function() { alert(1);}) 
    .click(function() {alert(2);}); 

// alert(1) is first 

我意识到是jQuery的,但在纯JS事件绑定这样做。

真正做到这一点的最好办法,是用deferreds或承诺,但我不知道如何在knockoutjs :(

+0

改变click'的'顺序和'chekced'绑定并一招订阅更改selectedFilterIds但搞砸的复选框的状态,所以我就在绑定更新的状态到'点击'方法bucheck框仍然显示以前的状态 – sll 2012-04-12 19:13:41

1

工作由于勾选复选框会同时触发选中,然后单击事件基本上同时,浏览器只是决定它将首先触发其中一个处理程序,所以一个简单的修复就是在您的点击处理程序中使用超时。

setTimeout(function() { stuff }, 1)应该工作。

把它放在你的点击处理程序中会跳出处理程序,让被检查的处理程序触发并执行,之后它会返回到你的超时回调中的代码(等待1ms后,如果你的处理程序是我很怀疑)

即使检查的处理程序在其他浏览器中首先触发,此解决方案仍然可以正常工作。

+0

感谢您的想法,但只要我有其他更多的本机选项,我会避免任何变通。我发现显式订阅使用'subscribe()'非常有趣的解决方案,因为我完全控制我做什么。顺便说一句,你认为事件的执行顺序在不同的浏览器中可能会有所不同吗?对我来说看起来很奇怪,但我并不擅长跨浏览器开发,所以谁知道 – sll 2012-04-12 19:15:42

+0

我不记得任何细节,但如果某些东西(比如老版本的IE;))将会洗牌甲板,我不会感到惊讶有关事件顺序 – 2012-04-12 19:39:14

+0

有趣的,我明白,这将是一个通用的解决方案。我不熟悉JavaScript中的超时,请稍微扩展您的示例? – sll 2012-04-12 19:48:40