在这种情况下,我正在寻找或可见最佳做法的
<div data-bind="visible: $root.obsVar()">
...
<input type="text" data-bind="value: $root.obsVar().someField" />
...
</div>
如果$root.obsVar()
未定义,则会引发错误。如果您将visible
更改为if
,问题将会遗漏,但需要重写html。如果div
中有很多murkup,则需要花费很多时间。是否有任何理由将$root.obsVar().someField
更改为$root.getSomeFieldValue
始终返回正确的值或未定义?或者也许还有其他技术不会增加开销并避免错误。
答案 0 :(得分:10)
这实际上取决于场景。来自docs:
if
扮演与visible
绑定类似的角色。不同之处在于,对于visible
,包含的标记始终保留在DOM中并始终应用其data-bind
属性 -visible
绑定仅使用CSS来切换容器元素的可见性。但是,if
绑定会物理地添加或删除DOM中包含的标记,并且只有在表达式为真时才对后代应用绑定。
在您的方案中,当if
为空时,在不使用someField
的情况下阻止错误的唯一方法是沿着这些方向执行某些操作:
data-bind="value: ($root.obsVar() == null) ? null : $root.obsVar().someField"
每次访问某个属性时都必须编写,这真的很烦人。它使代码更难维护,并且更容易犯错误 - 尤其是当您向obsVar
的属性添加新绑定时,因为您必须记住执行该空检查。
除非您在使用visible
的情况下看到明显的性能优势,否则我的建议是if
,因为您只需要在一个地方而不是多个地方写支票。
答案 1 :(得分:1)
正如David Sherret的回答所述,主要区别在于if
如果条件未满足,则DOM元素会消失,而visible
只会隐藏它们,但始终存在于DOM树。
主要结果是,如果您正在使用if
并且必须处理事件,则必须使用委派事件,或者每次重新创建元素时附加事件。当您使用KO时,通常不进行事件处理,因为您使用由KO处理的click
之类的绑定,因此您没有遇到此问题。但是你可以使用其他一些框架,比如验证器,jQuery UI日期选择器等,这些都很难与KO的if
一起正常工作。
答案 2 :(得分:0)
尝试使用$ root.obsVar而不使用()。这应该适用于if或visible。两者之间的区别在于&#34;可见&#34;只是隐藏了div,它仍然存在于DOM中,但是&#34;如果&#34;将它从DOM中删除。
答案 3 :(得分:0)
您可能会发现需要同时使用它们。
使用if
从DOM中删除标记 - 防止可能出现的JS错误,因此不占用页面空间。
然后使用visible
隐藏元素,直到页面完全加载。
<!-- ko if: whatever -->
<div data-bind="visible: true" style="display: none">
my content
</div>
<!-- /ko -->