淘汰赛deferUpdates与'if'绑定冲突 [英] Knockout deferUpdates conflict with 'if' binding
问题描述
我经常在挖空中使用if
绑定来隐藏某些内容,而且还有额外的好处,就是我不必担心if
内部的空引用错误.在此示例中,如果address()
为null,则将删除整个块,因此避免了必须对每个属性进行null检查的情况.如果我使用visible
绑定,情况就不会如此.
I very often use the if
binding in knockout to hide something, with the added bonus that I don't need to worry about null reference errors inside the if
. In this example if address()
is null then the whole block is removed so you avoid having to deal with null checking for every property. This would not be the case had I used the visible
binding.
<div data-bind="if: address()">
You live at:
<p data-bind="text: address().street.toUpperCase()"></p>
</div>
这是上面最简单的情况-是的,我通常会将此样式与<!-- ko -->
注释语法一起使用.
This is the simplest case above - and yes I would generally use this pattern with the <!-- ko -->
comment syntax.
实际上导致我出现问题的是当我使用更复杂的computed
值并启用ko.options.deferUpdates
选项时:
What is actually causing me problems is when I use a more complex computed
value and enable the ko.options.deferUpdates
option :
<div data-bind="if: hasAddress()">
You live at:
<p data-bind="text: address().street.toUpperCase()"></p>
</div>
可观察到的computed
的最简单实现可能是这样的:
The simplest implementation of this computed
observable might be something like this :
this.hasAddress = ko.computed(function () { return _this.address() != null; });
在我执行以下操作之前,这一切都很好:
This all works great until I do the following:
1)在创建可观察对象之前设置
ko.options.deferUpdates = true
.
2)address()
将开始为null,一切都很好
2) address()
will start off as null and everything is fine
3)将address()
设置为{ street: '123 My Street' }
.同样,一切正常.
3) set address()
to { street: '123 My Street' }
. Again everything works fine.
4)将address()
重置为空.我收到一个空错误,因为address().street
是
空:-(
4) reset address()
to null. I get a null error because address().street
is
null :-(
这里有个小提琴来说明问题: https://jsfiddle.net/g5gvfb7x/2/
Here is a fiddle to illustrate the problem : https://jsfiddle.net/g5gvfb7x/2/
不幸的是,由于微任务的运行顺序,它试图在if
绑定之前尝试重新计算text
绑定,因此您仍然会收到通常不会发生的空错误.
It seems that unfortunately due to the order in which the micro-tasks runs it tries to recalculate the text
binding before the if
binding and so you still get a null error that normally wouldn't occur.
我对此有点担心,因为我经常使用这种模式:-(
I'm a little scared about this since I use this pattern a lot :-(
推荐答案
使用deferUpdates
时,Knockout在内部使用dirty
事件通知所有计算出的可观察对象其依存关系的变化并安排更新,深度优先.之所以会出现此问题,是因为绑定会忽略dirty
事件并等待一个change
事件,该事件将以广度优先的顺序发生.
When using deferUpdates
, Knockout internally uses a dirty
event to notify all computed observables of a change in their dependencies and to schedule updates, which happens in depth-first order. The problem here occurs because bindings ignore the dirty
event and wait for a change
event, which will happen in a breadth-first order.
此修复必须在Knockout中进行,以使绑定响应dirty
事件.已经针对即将发布的版本(3.5.0)进行了检查: https://github. com/knockout/knockout/issues/2226
The fix has to happen in Knockout to make bindings respond to the dirty
events. This has already been checked in for the upcoming version (3.5.0): https://github.com/knockout/knockout/issues/2226
这篇关于淘汰赛deferUpdates与'if'绑定冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!