首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在数据绑定表达式中使用或不使用带可观测值的括号的时间

在数据绑定表达式中使用或不使用带可观测值的括号的时间
EN

Stack Overflow用户
提问于 2015-12-15 23:45:41
回答 1查看 1.5K关注 0票数 4

我已经在这个问题上看到了其他的线索,但我仍然感到困惑,我认为我在这里提出了一个不同的案例。

我使用显示模式将视图模型对象返回到我的HTML文档中。因此,我有一个视图模型对象,如下所示:

代码语言:javascript
复制
var vm = function() {
   var customProperty = ko.numbericObservable(0);

   return {
      customProperty: customProperty
   };
} ();

从这一点可以看出,customProperty被分配给一个可以观察到的、初始值为0的Knockout数字。

在包含上述JavaScript的HTML中,我有一个带有data属性的SPAN元素,该属性订阅了可观察到的customProperty,如下所示:

代码语言:javascript
复制
<span data-bind="text: customProperty" 
  id="customProperty" style="font-weight:bold"></span>

到现在为止还好。上面的内容工作得很好,这意味着每当我在脚本中更改customProperty的值时,SPAN中的文本就会立即更新。例如,我可以成功且容易地使用该表达式将可观察到的customProperty值从0更改为10:

代码语言:javascript
复制
vm.customProperty(10);

我的问题:

  1. 注意,我在引用数据绑定属性中的customProperty值时没有使用括号。为什么不需要括号?
  2. 我发现使用括号也有效:

我理解为什么使用括号有效(因为我正在读取可观察到的Knockout值)。但是为什么不需要括号呢?换句话说,为什么点1中的数据绑定表达式会工作呢?

  1. 最后,这个作业到底是怎么回事? var customProperty = ko.numericObservable(0);

customProperty最终是否持有指向名为customProperty()的函数的指针?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-16 09:17:42

  1. 当ko解析绑定时,它会检查表达式是否是可观察的,如您所知,这是一个函数。如果表达式是可观察的,ko会自动打开值以显示它,但它也允许订阅和通知。
  2. 在这种情况下,当ko解析表达式时,它会找到一个值,而不是一个可观察的值,因此,它也能正确地显示值(值更改>视图更新)。但是,您将失去从视图到值的绑定(输入值更改>可观察是不更新的),因为它不是可观察的。有关更多细节,请参见下面的解释和片段。
  3. customProperty是一个函数,特别是ko.observable,它意味着除了使用()(newValue)语法读取或设置值之外,还支持订阅和通知。

注意:使用括号和不使用括号之间的差别是巨大的。如果你这样做:

代码语言:javascript
复制
<input type="text" data-bind="value: customProperty" ...

正如我在1中解释的那样,ko发现customProperty是可观察的,因此当用户更改input中的值时,新值被写回可观测值。如果你这样做:

代码语言:javascript
复制
<input type="text" data-bind="value: customProperty()" ...

正如我在2中所解释的,ko找到了一个值,而不是一个可观察的值。因此,如果用户通过在input上键入来更改它的值,则新值不会反馈给可观测值,因为ko不知道它是可观测的。(但是如果更新了可观测值,视图就会发生变化,因为依赖关系是在表达式计算期间发现和订阅的)。

代码语言:javascript
复制
var vm = {
	customProperty: ko.observable(10)
};

ko.applyBindings(vm);
代码语言:javascript
复制
body {
  font-family: Segoe, Arial
}
代码语言:javascript
复制
<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,这取决于执行的分支。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34301591

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档