在数据绑定表达式中,何时使用或不使用带可观察性的括号
When to use or not use parentheses with observables in data-binding expressions
我已经看到了关于这方面的其他线程,但我仍然感到困惑,我认为我在这里提出了一个不同的情况。
我正在使用揭示模式将视图模型对象返回到我的HTML文档中。因此,我有一个视图模型对象,看起来像这样:
var vm = function() {
var customProperty = ko.numbericObservable(0);
return {
customProperty: customProperty
};
} ();
从中,您可以看到customProperty正被分配给一个初始值为0的Knockout数值可观察对象。
在包含上述JavaScript的HTML文档中,我有一个SPAN元素,该元素具有订阅customProperty observable的数据绑定属性,如下所示:
<span data-bind="text: customProperty"
id="customProperty" style="font-weight:bold"></span>
到目前为止,一切都很好。上面的操作很好,这意味着每当我在脚本中更改customProperty的值时,SPAN中的文本就会立即更新。例如,我可以成功地轻松地使用这个表达式将customProperty observable的值从0更改为10:
vm.customProperty(10);
我的问题:
请注意,在引用数据绑定属性中的
customProperty
值时,我没有使用括号。为什么不需要括号?我发现使用括号也有效:
我理解为什么使用括号有效(因为我正在阅读可观察到的Knockout的值)。但是为什么不需要括号呢?换句话说,为什么第1点中的数据绑定表达式会起作用?
最后,这项任务到底发生了什么?
var customProperty = ko.numericObservable(0);
customProperty
最终是否持有指向名为customProperty()
的函数的指针?
-
当ko解析绑定时,它会检查表达式是否是可观察的,正如您所知,它是一个函数。如果表达式是可观察的,ko会自动打开值以显示它,但它也允许订阅和通知。
-
在这种情况下,当ko解析表达式时,它会找到一个值,而不是一个可观察的值,因此,它也可以正确地显示值(值更改>视图更新)。但是,您将丢失从视图到值的绑定(输入值更改>可观察不更新),因为它不是可观察的。有关更多详细信息,请参阅下面的说明和片段。
-
customProperty
是一个函数,特别是ko.observable
,这意味着除了使用()
或(newValue)
语法读取或设置值之外,它还支持订阅和通知
注意:使用括号和不使用括号之间的区别是巨大的。如果你这样做:
<input type="text" data-bind="value: customProperty" ...
正如我在1中所解释的,ko发现customProperty
是一个可观测值,因此当用户更改input
中的值时,新值会写回可观测值。如果你这样做:
<input type="text" data-bind="value: customProperty()" ...
正如我在2中所解释的,ko找到了一个值,而不是一个可观察的值。因此,如果用户通过键入input
来更改其值,则新值不会反馈给可观察对象,因为ko不知道它是可观察对象。(但是,如果更新了可观察值,则视图会发生更改,因为依赖关系是在表达式求值期间发现和订阅的)。
var vm = {
customProperty: ko.observable(10)
};
ko.applyBindings(vm);
body {
font-family: Segoe, Arial
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
data-bind="value: customProperty()"<br/>
<input type="text" data-bind="value: customProperty(), valueUpdate: 'keyup'"/><br/>
If you change the input text, customProperty is not updated
<br/><br/>
data-bind="value: customProperty"<br/>
<input type="text" data-bind="value: customProperty, valueUpdate: 'keyup'"/><br/>
If you change the input text, customProperty changes
<br/><br/>
customProperty value: <span data-bind="text: customProperty"/>
在其他框架中,如Angular,它不使用函数,而是使用带有JavaScript setter和getter的属性,这样语法就不需要括号了。具有setter和getter的属性可以像其他任何属性一样进行读取和写入,但在幕后,setter或getter中的代码会运行,从而允许进行订阅和通知。
注2(因为评论中有问题)。你可以这样想:当ko解析绑定表达式时,它会立即评估整个表达式,并检查结果是否是可观察的。所以,当你有一个这样的表达式:customProperty == 10
时,当ko对它进行求值时,它发现它不是一个可观察的(而是一个布尔值),并且不需要额外的步骤来获得值。结果将始终为false,因为customProperty
是function
,因此为'!=10’。如果将表达式更改为以下表达式:customProperty() == 10
,则自定义特性值将被()
展开,并且比较将按预期进行。顺便说一句,尽量不要在绑定表达式中包含代码:在模型中使用计算的可观察性(如果可能的话,最好是纯计算的)要好得多
注释2的控制台实验
键入:var vm = {customProperty: ko.observable(10)}
以创建视图模型。
键入:vm.customProperty()
,您将看到10
。
键入:vm.customProperty
,您将看到function ...
。
键入:vm.customProperty() == 10
,您将看到true
(难怪,10 == 10
)
键入:vm.customProperty == 10
,您将获得false
(因为function != 10
)
此外,键入ko.isObservable(vm.customProperty)
,您将看到true
。ko就是这么做的。所以ko知道它必须打开价值。键入ko.unwrap(vm.customProperty)
,您将看到10
最后,键入ko.isObservable(vm.customProperty == 10)
或ko.isObservable(vm.customProperty() == 10)
。在这两种情况下,您都会得到false
,因为在这两个情况下,表达式都是bool
,而不是可观察的函数。Ko不会对表达式进行反编译并逐个检查。这将是在第一个表达式中发现customProperty
是可观察的并且应该被展开的唯一方法。但是ko并不是那样做的。
注3:当在原始评估中使用可观测属性且其值发生变化时,表达式作为计算的可观测值将重新评估。请注意,如果在第一次评估中只访问一个可观察属性,即使代码中包含对其他可观察属性的引用,也只有当访问的可观察属性更改其值时,才会对其进行重新评估。其他可观察性的变化不会被"观察到"。典型的情况是if
,它取决于不同的可观测值,这些可观测值取决于执行的分支
- knockoutjs可观察数组
- 如何收集Knockout可观察性以放入JSON
- 在隐藏值上调用 jQuery .trigger('change') 会破坏与 KNOCKOUT 相关的可观察性
- Knockout.js性能-有多少可观察性
- 更改可观察数组会更改自定义绑定处理程序knockoutjs的可见性
- Knockout.js:在可选定义的值上计算可观察性
- 如何使用ES6在Ember中声明可观察性或计算属性
- RXJS5 - 按每个对象包含的可观察性过滤对象数组
- .replace() 表达式未在计算可观察量中更新
- Angular2 Http 请求返回没有映射方法的可观察性
- 在数据绑定表达式中,何时使用或不使用带可观察性的括号
- 在knockoutjs中计算的可观察性;更改时不更新
- 如何增加knockout.js的可观察性
- 如何通过多个$.ajax调用实现异步计算可观察性
- 敲除绑定顺序/不带可观察性
- javascript命名函数表达式-作用域可访问性
- knockoutjs:计算级联数组(复杂视图模型)中的可观察性和this指针
- 在响应式表达式中,是什么启动了一个热门的可观察序列?
- 在knockoutjs中将正则表达式绑定为一个可观察对象
- 使用计算的可观察性的对象范围