何时在数据绑定表达式中使用或不使用带有可观察值的括号 [英] When to use or not use parentheses with observables in data-binding expressions

查看:57
本文介绍了何时在数据绑定表达式中使用或不使用带有可观察值的括号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我还看到了其他主题,但我仍然感到困惑,我想在这里提出一个不同的案例.

I have seen other threads on this but I'm still confused and I think I am presenting a different case here.

我正在使用显示模式将视图模型对象返回到我的HTML文档.因此,我有一个看起来像这样的视图模型对象:

I'm using the revealing pattern to return a view model object to my HTML document. Thus, I have a view model object that looks something like this:

var vm = function() {
   var customProperty = ko.numbericObservable(0);

   return {
      customProperty: customProperty
   };
} ();

由此,您可以看到将customProperty分配给了可观察到的,初始值为0的Knockout数字.

From this, you can see that customProperty is being assigned to a Knockout numeric observable with an initial value of 0.

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

In the HTML document that includes the JavaScript above, I have a SPAN element with a data-bind attribute that subscribes to the customProperty observable, like this:

<span data-bind="text: customProperty" 
  id="customProperty" style="font-weight:bold"></span>

到目前为止,太好了.上面的方法工作得很好,这意味着每当我在脚本中更改customProperty的值时,SPAN中的文本就会立即更新.例如,我可以成功并轻松地使用此表达式将可观察到的customProperty的值从0更改为10:

So far, so good. The above works just fine, meaning that whenever I change the value of customProperty in script, the text in the SPAN updates right away. For example, I can successfully and easily use this expression to change the value of the customProperty observable from 0 to 10:

vm.customProperty(10);

我的问题:

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

  1. Notice that I did not use parentheses when referring to the customProperty value in the data-bind attribute. Why are parentheses not required?

我发现使用括号也可以:

I discovered that using parentheses also works:

我了解使用括号的原因(因为我正在读取可观察到的淘汰赛的值).但是为什么不需要括号呢?换句话说,为什么第1点的数据绑定表达式完全起作用?

I understand why using parentheses works (because I am reading the value of a Knockout observable). But why are the parentheses not NEEDED? In other words, why would the data-bind expression in point 1 work at all?

  1. 最后,这项作业实际上是怎么回事?

  1. Finally, what actually is going on in this assignment?

var customProperty = ko.numericObservable(0);

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

Does customProperty end up holding a pointer to a function called customProperty()?

推荐答案

  1. 当ko解析绑定时,它将检查该表达式是否是可观察的,如您所知,它是一个函数.如果该表达式是可观察到的,ko将自动解包该值以显示它,但它也允许订阅和通知.

  1. When ko parses the bindings, it checks if the expression is an observable, which, as you know is a function. If the expression is an observable, ko automatically unwraps the value to show it, but it also allows subscriptions and notifications.

在这种情况下,当ko解析表达式时,它将找到一个值,而不是一个可观察的值,因此,它也可以正确显示该值(值更改>视图更新).但是,您将丢失视图与值的绑定(输入值更改> observable不会更新),因为它不是可观察的.有关更多详细信息,请参见下面的说明和摘要.

In this case, when ko parses the expression, it finds a value, not an observable, so, it also works correctly to show the value (value changes > view updates). However, you'd lose the binding from the view to the value (input value changes > observable is not updated), because it's not an observable. For more details, see explanation and snippet below.

customProperty是一个函数,尤其是ko.observable,这意味着它支持订阅和通知,除了使用()(newValue)语法

customProperty is a function, in particular a ko.observable, which means that supports subscriptions and notifications, apart form reading or setting the value using the () or (newValue) syntax

注意:使用和不使用括号之间的差异非常大.如果您这样做:

NOTE: the difference between using and not using parentheses is huge. If you do this:

<input type="text" data-bind="value: customProperty" ...

正如我在1中解释的那样,

ko发现customProperty是可观察的,因此当用户更改input中的值时,新值将写回到可观察的对象.如果您这样做:

as I explain in 1, ko finds that customProperty is an observable, so when the user changes the value in the input, the new value is written back to the observable. If you do this:

<input type="text" data-bind="value: customProperty()" ...

正如我在2中解释的那样,ko找到了一个值,而不是一个可观察的值.因此,如果用户通过键入input的值来更改input的值,则新值不会反馈到可观察值,因为ko不知道它是可观察值. (但是,如果可观察值被更新,则视图将发生变化,因为在表达式求值期间已发现并订阅了依赖项.)

as I explain in 2, ko finds a value, not an observable. So, if the user changes the value of the input by typing on it, the new value is not fed back to the observable, because ko doesn't know it's an observable. (But if the observable value is updated, the view changes, because the dependency is discovered and subscribed during the expression evaluation).

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 设置者 getters ,这样语法就不需要括号了.具有setts和getter的属性可以像其他任何属性一样读写,但是在后台运行setter或getter中的代码,从而可以进行订阅和通知.

In other frameworks, like Angular, instead of using functions, it uses properties with JavaScript setters and getters so that the syntax never needs parentheses. Properties with settes and getters are read and written as any other property, but behind the scenes the code in the setter or getter runs, allowing subscriptions and notifications to happen.

注2(由于评论中的问题).您可以这样想:ko解析绑定表达式时,它将立即评估整个表达式并检查结果是否可观察.因此,当您具有这样的表达式时:customProperty == 10,当ko对其进行评估时,它发现它不是可观察的(而是布尔值),并且无需采取额外的步骤即可获取该值.结果将始终为false,因为customPropertyfunction,因此为'!= 10'.如果将表达式更改为以下表达式:customProperty() == 10定制属性值将由()展开,并且比较将按预期进行.顺便说一句,不要在绑定表达式中包含代码:最好使用计算的可观察对象 (如果可能,最好使用纯计算).

NOTE 2 (because of question in the comment). You can think of it like this: when ko parses a binding expression, it evaluates the whole expression at once and checks if the result is an observable. So, when you have an expression like this: customProperty == 10, when ko evaluates it, it finds it's not an observable (but a boolean) and takes no extra steps to get the value. The result will always be false, because customProperty is a function, and thus is '!= 10'. If you change the expression to this one: customProperty() == 10 the custom property value will be unwrapped by the (), and the comparison will work as expected. By the way, try not to include code in the binding expressions: it's much better to use computed observables (better pure computeds, if possible) in your model.

键入:var vm = {customProperty: ko.observable(10)}以创建视图模型.

Type: var vm = {customProperty: ko.observable(10)} to create a view model.

类型:vm.customProperty(),结果将显示10.

类型:vm.customProperty,结果将显示function ....

类型:vm.customProperty() == 10,您会看到true(难怪,10 == 10)

Type: vm.customProperty() == 10, and you'll see true (no wonder, 10 == 10)

类型:vm.customProperty == 10,您会得到false(因为function != 10)

Type: vm.customProperty == 10, and you'll get false (because function != 10)

此外,键入ko.isObservable(vm.customProperty),您将看到true.那是ko所做的.因此,ko知道必须解开价值.输入ko.unwrap(vm.customProperty),您会看到10

Furthermore, type ko.isObservable(vm.customProperty) and you'll see true. That's what ko does. So ko knows it must unwrap the value. Type ko.unwrap(vm.customProperty) and you'll see 10

最后,键入ko.isObservable(vm.customProperty == 10)ko.isObservable(vm.customProperty() == 10).在这两种情况下,都会得到false,因为在两种情况下表达式都是bool,而不是可观察的函数. Ko不会反解析表达式并逐个检查它.这是在第一个表达式中发现customProperty是可观察的并且应该解包的唯一方法.但是ko不会那样做.

Finally, type ko.isObservable(vm.customProperty == 10) or ko.isObservable(vm.customProperty() == 10). In both cases you'll get false, becase the expression is a bool in both cases, and not an observable function. Ko doesn't decompse the expression and check it piece by piece. That would be the only way to discover in the first expression that customProperty is an observable and should be unwrapped. But ko does not do it in that way.

注意3:当在原始评估中使用可观察属性并更改其值时,将重新评估作为可计算观察值的表达式.请注意,如果在第一次评估中您仅访问一个可观察的属性,即使代码包含对其他可观察对象的引用,则仅当所访问的可观察的对象更改其值时,才会重新评估它.其他可观察变量的变化将不会被观察".典型的情况是if,取决于所执行的分支,该值取决于不同的可观察对象

NOTE 3: expressions, as computed observables, are re-evaluated when an observable property was used in the original evaluation and it changes its value. Be warned that if in the first evaluation you only access an observable property, even if the code contains references to other observables, it will only be re-evaluated when the accessed observable changes its value. Changes on the other observables won't be "observed". The typical case is an if that depends on different observables depending on the executed branch

这篇关于何时在数据绑定表达式中使用或不使用带有可观察值的括号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆