Knockoutjs:同时使用单击和选中绑定时绑定评估的顺序

Knockoutjs: Order of the bindings evaluation when using click and checked bindings in the same time

本文关键字:绑定 定时 评估 顺序 单击 Knockoutjs      更新时间:2023-09-26

我不知道如何访问已通过在与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绑定,但得到了相同的结果。也许我以错误的方式这样做并错过了一些明显的东西?

您可以通过执行以下操作来订阅对 selectedFilterId 的更改

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

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

setTimeout(function() { stuff }, 1)这样的东西应该有效。

将其放入您的点击处理程序中会"跳出"处理程序,让检查的处理程序触发并执行,之后它会返回到超时回调中的代码(如果您检查的处理程序足够快,则等待 1 毫秒后完成在此之前,我对此表示怀疑)

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

通常,方法按照您很好地绑定它们的顺序执行..绑定它们..看起来您首先绑定单击。不确定 knockoutjs 如何从数据绑定属性中处理这个问题?

例如

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

我意识到这是jquery,但是纯js中的事件绑定也这样做。

真的最好的方法是使用延期或承诺,但我不知道这在 knockoutjs :( 中是如何工作的