【问题标题】:Knockoutjs: Order of the bindings evaluation when using click and checked bindings in the same timeKnockoutjs:同时使用单击和检查绑定时的绑定评估顺序
【发布时间】:2012-04-24 05:57:07
【问题描述】:

我不知道如何在与click 绑定关联的方法中访问已由checked 绑定更新的值?

似乎checked 绑定在click 绑定之后进行评估,因为在click 绑定方法/处理程序中我无法访问computed 属性值,该值取决于与checked 绑定同步的数组。

单个复选框的模板:

<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() 中我只是调用 alert(topLevelViewModel.aggregatedSelectedIds()) 以确保此属性表示当前选定过滤器的列表。

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

【问题讨论】:

    标签: javascript binding mvvm knockout.js


    【解决方案1】:

    您可以通过以下方式订阅对 selectedFilterIds 的更改

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

    【讨论】:

      【解决方案2】:

      由于选中复选框将基本上同时触发选中和点击事件,浏览器只是决定它会首先触发其中一个处理程序,因此一个简单的解决方法是在您的点击处理程序中使用超时。

      setTimeout(function() { stuff }, 1) 之类的东西应该可以工作。

      把它放在你的点击处理程序中会“跳”出处理程序,让被检查的处理程序触发并执行,然后它会返回到你的超时回调中的代码(如果你的检查处理程序很快,在等待 1ms 之后足以在此之前完成,我对此表示怀疑)

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

      【讨论】:

      • 感谢您的想法,但只要我有其他更多本地选项,我会避免任何变通方法。我发现使用subscribe() 的显式订阅非常有趣,因为我可以完全控制自己的工作。顺便说一句,您认为事件的执行顺序在不同的浏览器中可能会有所不同吗?对我来说看起来很奇怪,但我不是跨浏览器开发方面的专家,所以谁知道
      • 我不记得任何细节,但如果某些东西(比如旧版本的 IE ;))会在事件顺序方面稍微洗牌,我不会感到惊讶
      • 有趣,我知道这将是一个通用的解决方案。我不熟悉 javascript 中的超时,您能否稍微扩展一下您的示例?
      • 这很简单。您只需将要执行的代码放在我有stuff 的地方。第二个参数1 是您希望它等待的毫秒数。见:developer.mozilla.org/en/DOM/window.setTimeout
      • 试过这个,它对绑定集合有一个技巧,所以在我的处理程序中我可以看到更新的状态,但是复选框被弄乱了,因为代表以前的状态(最后一个选中的复选框保持未选中状态,直到我执行下一个选择)。
      【解决方案3】:

      通常,方法会按照您的顺序绑定和执行.. 绑定它们.. 看起来您首先绑定点击。不知道从数据绑定属性中敲除js如何处理这个?

      例如

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

      我知道那是 jquery,但是纯 js 中的事件绑定也是如此。

      真正做到这一点的最好方法是延迟或承诺,但我不知道这在 knockoutjs 中是如何工作的:(

      【讨论】:

      • 更改clickchekced 绑定的顺序有一个技巧,但会弄乱复选框的状态,所以我得到了绑定到click 方法的更新状态,bucheck 框仍然显示以前的状态
      猜你喜欢
      • 1970-01-01
      • 2012-01-18
      • 1970-01-01
      • 2013-05-02
      • 1970-01-01
      • 1970-01-01
      • 2016-04-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多