Knockout.js中data-bind括号工作机制及无括号异常问题咨询
Knockout绑定表达式不加括号的逻辑问题解析
输入框只读状态绑定问题
你的输入框代码:
<input type="text" data-bind="attr: {readonly: isViewMode || isNotEditableInvoice}, value: model.DateFormatted" />
异常现象
- 当
isViewMode返回true、isNotEditableInvoice返回false时,readonly判定为true(符合预期); - 当
isViewMode返回false、isNotEditableInvoice返回true时,readonly却判定为false(不符合预期)。
按钮显示状态绑定问题
你的按钮代码:
<input type="button" value="Save" data-bind="visible: !isReadOnly || isEditableInvoice,click: onUpdate" />
异常现象
- 当
isReadOnly返回false、isEditableInvoice返回false时,不加括号visible被设为true(不符合预期); - 给
isReadOnly加括号后结果正常。
原因解析
核心问题在于:Knockout的可观察对象(observable)本质是JavaScript函数,只有直接作为绑定值时才会自动解包(调用函数获取内部值),放到逻辑运算符(||、&&、!)等表达式中时,不会自动解包,你操作的是函数本身而非内部值。
输入框案例拆解
- 当
isViewMode是返回true的observable:isViewMode作为函数本身是JS的“真值”,isViewMode || isNotEditableInvoice会直接返回isViewMode函数。Knockout处理readonly时,会自动解包这个函数取内部值true,所以readonly生效(符合预期)。 - 当
isViewMode是返回false的observable:isViewMode函数依然是真值,||运算符会直接返回第一个真值(即isViewMode函数),Knockout解包后取内部值false,导致readonly不生效(不符合预期),完全忽略了isNotEditableInvoice的实际值。
按钮案例拆解
- 当
isReadOnly是返回false的observable:!isReadOnly是对函数本身取反,函数是真值,取反后结果为false。此时false || isEditableInvoice中,isEditableInvoice如果是observable函数(依然是真值),表达式会返回isEditableInvoice函数,Knockout解包后若其内部值为false,理论上visible应为false,但你看到的异常是因为函数本身被当成真值处理,本质都是未手动解包导致的。
解决方法
所有在逻辑表达式中的observable必须手动加括号调用,获取其实际内部值:
<!-- 输入框修正后 --> <input type="text" data-bind="attr: {readonly: isViewMode() || isNotEditableInvoice()}, value: model.DateFormatted" /> <!-- 按钮修正后 --> <input type="button" value="Save" data-bind="visible: !isReadOnly() || isEditableInvoice(), click: onUpdate" />
内容的提问来源于stack exchange,提问作者Foreastbtch
相关产品推荐
相关产品推荐

