data-bind 语法
knockout 声明式绑定系统提供了一种简洁而强大的方式将数据链接到UI。绑定到简单的数据属性或使用单个绑定通常是简单而明显的。对于更复杂的绑定,它有助于更好地理解 knockout 绑定系统的行为和语法。
绑定语法
绑定由两个项组成,绑定名称和值,用冒号分隔。下面是单个简单绑定的示例
Today's message is: <span data-bind="text: myMessage"></span>
元素可以包含多个绑定(相关的或不相关的),每个绑定之间用逗号分隔。下面是一些例子
<!-- 相关绑定:valueUpdate是值的参数 -->
Your value: <input data-bind="value: someValue, valueUpdate: 'afterkeydown'" />
<!-- 不相关绑定 -->
Cellphone: <input data-bind="value: cellphoneNumber, enable: hasCellphone" />
绑定名称通常应匹配已注册的绑定(内置或自定义),或作为另一个绑定的参数。如果名称与这两个名称都不匹配,则 knockout 将忽略它(没有任何错误或警告)。因此,如果绑定似乎不起作用,首先检查名称是否正确。
绑定值
绑定值可以是( value, variable, or literal)单个值、变量、文本或几乎任何有效的JavaScript表达式。下面是各种绑定值的示例:
<!-- variable (usually a property of the current view model -->
<!-- 变量(通常是当前视图模型的属性) -->
<div data-bind="visible: shouldShowMessage">...</div>
<!-- comparison and conditional, template literals -->
<!-- 比较和条件,模板文本 -->
The item is <span data-bind="text: price() > 50 ? `expensive` : `cheap`"></span>.
<!-- function call and comparison -->
<!-- 函数调用与比较 -->
<button data-bind="enable: parseAreaCode(cellphoneNumber()) != '555'">...</button>
<!-- function expression -->
<!-- 函数表达式 -->
<div data-bind="click: function (data) { myFunction('param1', data) }">...</div>
<!-- object literal (with unquoted and quoted property names) -->
<!-- 对象文本(带有非引号和引号属性名) -->
<div data-bind="with: {emotion: 'happy', 'facial-expression': 'smile'}">...</div>
这些示例表明,该值可以是任意JavaScript表达式。即使逗号用大括号、方括号或圆括号括起来也没问题。当值是对象文字时,对象的属性名必须是有效的JavaScript标识符或括在引号中。如果绑定值是无效表达式或引用未知变量,则删除将输出错误并停止处理绑定。
空格
绑定可以包含任意数量的空白(空格、制表符和换行),因此您可以随意使用它来安排绑定。下面的例子都是等价的:
<!-- no spaces -->
<select data-bind="options:availableCountries,optionsText:'countryName',value:selectedCountry,optionsCaption:'Choose...'"></select>
<!-- some spaces -->
<select data-bind="options : availableCountries, optionsText : 'countryName', value : selectedCountry, optionsCaption : 'Choose...'"></select>
<!-- spaces and newlines -->
<select data-bind="
options: availableCountries,
optionsText: 'countryName',
value: selectedCountry,
optionsCaption: 'Choose...'"></select>
注释
绑定可以包括JavaScript样式的注释(// ...和/.../)。 例如:
<select data-bind="
options: availableCountries, // Only list countries that are available
optionsText: 'countryName',
/* optionsValue: 'countryId',
value: selectedCountry, */ // These two bindings are not processed
optionsCaption: 'Choose...'"></select>
跳过绑定值
如果指定没有值的绑定,则 knocout 将使绑定 undefined
值。例如
<span data-bind="text">Text that will be cleared when bindings are applied.</span>
当与绑定预处理相匹配时,这种功能尤其有用,因为绑定预处理可以为绑定分配一个默认值。
绑定上下文
绑定上下文是一个对象,它包含可以从绑定引用的数据。在应用绑定时,knockout 会自动创建和管理绑定上下文的层次结构。层次结构的根级别引用您提供给ko.applyBindings(viewModel)
的viewModel
参数。然后,每次使用控制流绑定(例如with
或foreach
)时,都会创建引用嵌套视图模型数据的子绑定上下文。
绑定上下文提供了以下特殊属性,您可以在任何绑定中引用这些属性:
- $parent
这是父级上下文中的视图模型对象,在当前上下文之外的视图模型对象。在根上下文中,这是未定义的。例子
<h1 data-bind="text: name"></h1>
<div data-bind="with: manager">
<!-- Now we're inside a nested binding context -->
<span data-bind="text: name"></span> is the
manager of <span data-bind="text: $parent.name"></span>
</div>
-
$parents
这是一个表示所有父级视图模型的数组
$parents[0]
是来自父级上下文的视图模型(即,与$parent
相同)
$parents[1]
是来自祖父母上下文的视图模型
$parents[2]
是来自曾祖父上下文的视图模型
...等等。
-
$root
这是根上下文中的主视图模型对象,即,最上层的父级上下文。它通常是传递给ko.applyBindings
的对象。
它相当于$parents[$parents.length - 1]
。
-
$component
如果您在特定组件模板( component template)的上下文中,那么$component
引用该组件的viewmodel
。它是特定于组件的$root
。在嵌套组件的情况下,$component
引用最近组件的viewmodel
。
这很有用,例如,如果组件的模板包含一个或多个foreach
块,您希望在其中引用组件视图模型上的某些属性或函数,而不是当前数据项。
-
$data
这是当前上下文中的视图模型对象。在根上下文中,$data
和$root
是等价的。在嵌套绑定上下文中,该参数将被设置为当前数据项(例如,在with: person
绑定中,$data
将被设置为person
)。当您想要引用viewmodel本身而不是viewmodel上的属性时,$data
非常有用。 例:
<ul data-bind="foreach: ['cats', 'dogs', 'fish']">
<li>The value is <span data-bind="text: $data"></span></li>
</ul>
-
$index (只能在foreach绑定中使用)
这是由foreach
绑定呈现的当前数组项的从零开始的索引。与其他绑定上下文属性不同.$index
是一个可观察的对象,当项目的索引发生变化时(例如,如果项目被添加到数组中或从数组中删除),$index就会被更新。
-
$parentContext
这指的是父级别的绑定上下文对象。 这与$parent
不同,后者指的是父级别的数据(非绑定上下文)。例如,如果您需要从内部上下文访问外部foreach
项的索引值(用法:$parentContext.$index
),那么这是非常有用的。这在根上下文中没有定义。
-
$rawData
这是当前上下文中的原始视图模型值。 通常这与$data
相同,但是如果提供给Knockout的视图模型包含在一个 observable 中,$data
将是展开的视图模型,$rawData
将是observable
本身。
-
$componentTemplateNodes
如果是在特定组件模板的上下文中,则$componentTemplateNodes
是一个数组,其中包含传递给该组件的任何DOM节点。这使得构建接收模板的组件变得很容易,例如,一个网格组件接受一个模板来定义它的输出行。有关完整示例,请参见将标记传递到组件。
以下特殊变量也可以在绑定中使用,但不属于绑定上下文对象的一部分
-
$context
这引用当前绑定上下文对象。如果您想访问可能存在于视图模型中的上下文属性,或者您想将上下文对象传递给视图模型中的helper函数,那么这可能很有用。
-
$element
这是当前绑定的元素DOM对象(对于虚拟元素,它将是注释DOM对象)。如果绑定需要访问当前元素的属性,这将非常有用。例子
<div id="item1" data-bind="text: $element.id"></div>
在自定义绑定中控制或修改绑定上下文
与内置的with
和foreach
绑定一样,自定义绑定可以更改其后代元素的绑定上下文,或者通过扩展绑定上下文对象提供特殊属性。这将在创建控制后代绑定的自定义绑定中详细描述。