我已经在这个问题上看到了其他的线索,但我仍然感到困惑,我认为我在这里提出了一个不同的案例。
我使用显示模式将视图模型对象返回到我的HTML文档中。因此,我有一个视图模型对象,如下所示:
var vm = function() {
var customProperty = ko.numbericObservable(0);
return {
customProperty: customProperty
};
} ();从这一点可以看出,customProperty被分配给一个可以观察到的、初始值为0的Knockout数字。
在包含上述JavaScript的HTML中,我有一个带有data属性的SPAN元素,该属性订阅了可观察到的customProperty,如下所示:
<span data-bind="text: customProperty"
id="customProperty" style="font-weight:bold"></span>到现在为止还好。上面的内容工作得很好,这意味着每当我在脚本中更改customProperty的值时,SPAN中的文本就会立即更新。例如,我可以成功且容易地使用该表达式将可观察到的customProperty值从0更改为10:
vm.customProperty(10);我的问题:
customProperty值时没有使用括号。为什么不需要括号?我理解为什么使用括号有效(因为我正在读取可观察到的Knockout值)。但是为什么不需要括号呢?换句话说,为什么点1中的数据绑定表达式会工作呢?
var customProperty = ko.numericObservable(0);customProperty最终是否持有指向名为customProperty()的函数的指针?
发布于 2015-12-16 09:17:42
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"/>
在其他框架中,比如角,它不使用函数,而是使用带有JavaScript 策划人和吸气器的属性,这样语法就不再需要括号了。带有settes和getter的属性作为任何其他属性被读取和写入,但是在幕后,setter或getter中的代码运行,允许订阅和通知发生。
注2(由于注释中的问题)。您可以这样想:当ko解析一个绑定表达式时,它立即计算整个表达式,并检查结果是否是可观察的。因此,当您有这样一个表达式:customProperty == 10__,当ko计算它时,它会发现它不是一个可观察的(而是一个布尔值),并且不会采取额外的步骤来获得值。结果总是错误的,因为customProperty是一个function__,因此是'!= 10‘。如果将表达式更改为:customProperty() == 10,则自定义属性值将由()__解压,比较将按预期的方式工作。顺便说一下,尽量不要在绑定表达式中包含代码:在模型中使用http://knockoutjs.com/documentation/computedObservables.html (如果可能的话,使用更好的http://knockoutjs.com/documentation/computed-pure.html )要好得多。
注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,这取决于执行的分支。
https://stackoverflow.com/questions/34301591
复制相似问题