Skip to content

Latest commit

 

History

History
150 lines (86 loc) · 7.98 KB

05.md

File metadata and controls

150 lines (86 loc) · 7.98 KB

五、外观绑定

在上一章中,我们看到了 Quinch . js 的控制流绑定如何为视图代码提供一个基本的模板系统。控制流绑定为应用提供了可视化结构,但是一个成熟的模板系统需要的不仅仅是结构。knockout. js 的外观绑定让您可以精确控制单个元素的样式和格式。

在撰写本文时,knockout. js 附带了六个绑定来控制 HTML 元素的外观:

  • text: <value>—设置元素的内容。
  • html: <value>—设置元素的 HTML 内容。
  • visible: <condition>-根据特定条件显示或隐藏元素。
  • css: <object>—向元素添加 CSS 类。
  • style: <object>—定义元素的style属性。
  • attr: <object>—向元素添加任意属性。

像所有的 knockout. js 绑定一样,外观绑定总是出现在 HTML 元素的data-bind属性内部。但是与前一章的控制流绑定不同,外观绑定只影响它们相关的元素——它们不改变模板块或绑定上下文。

文本绑定

text绑定是敲除的基础。正如我们已经看到的,text绑定显示了 HTML 元素内部的属性值:

            <td data-bind='text: name'></td>

您应该只在文本级元素上使用text绑定(例如,<a><em><span>等)。),尽管从技术上讲,它可以应用于任何 HTML 元素。作为其参数,text绑定采用任何数据类型,并在呈现之前将其转换为字符串。text绑定将转义 HTML 实体,因此可以用来安全地显示用户生成的内容。

图 16:视图中自动转义的 HTML 实体的text绑定

还值得指出的是,knockout. js 在幕后管理跨浏览器问题。对于 IE,它使用innerText属性,对于火狐和相关浏览器,它使用textContent

html 绑定

html绑定允许您将字符串呈现为 HTML 标记。如果您想要在视图模型中动态生成标记并在模板中显示它,这将非常有用。例如,您可以在我们的Product对象上定义一个名为formattedName的计算可见性,它包含一些 HTML:

        function Product(name, price, tags, discount) {       ...       this.formattedName = ko.computed(function() {         return "<strong>" + this.name() + "</strong>";       }, this);     }

然后,您可以使用html绑定呈现格式化名称:

      <span data-bind='html: featuredProduct().formattedName'></span>

虽然这违背了将内容与呈现分开的目标,但是html绑定如果使用得当,可以证明是一个通用的工具。

图 17:视图中html绑定呈现 HTML 实体

无论何时渲染动态 HTML——无论是通过html绑定还是 ASP。NET—始终确保标记已经过验证。如果需要显示不可信的内容,应该使用text绑定,而不是html

在前面的片段中,还要注意featuredProduct是一个可观测的对象,所以底层对象必须用空的函数调用来引用,而不是直接用featuredProduct.formattedName访问属性。同样,这是 knockout 初学者的常见错误。

可见绑定

很像ififnot绑定,visible绑定允许您根据特定条件显示或隐藏元素。但是,visible绑定并没有将元素从 DOM 中完全移除,而是简单地将一个display: none声明添加到元素的style属性中。例如,我们可以将现有的if绑定更改为visible绑定:

            <td data-bind='visible: discount() > 0' style='color: red'>

下面的代码示例显示了ifvisible版本的结果 HTML。本例假设条件评估为false:

    <!-- Using if binding: --> <td data-bind="if: discount() > 0" style="color: red"></td>
     <!-- Using visible binding: --> <td data-bind='visible: discount() > 0'     style='color: red; display: none'>
      You saved <span data-bind='text: formattedDiscount'></span>!!! </td>

决定何时使用visibleif很大程度上取决于上下文。在这种情况下,实际上最好使用if绑定,这样空的<td>会为每行创建相同数量的列。

该绑定采用与ififnot绑定相同的参数。条件可以是视图模型的属性、JavaScript 表达式或返回布尔值的函数。

css 绑定

css绑定允许您根据特定条件为 HTML 元素定义 CSS 类。它不是将条件作为参数,而是将包含 CSS 类名的对象作为属性名,将应用该类的条件作为值。这最好用一个例子来解释。

比方说,当一个产品的折扣超过 15%时,你想引起额外的注意。一种方法是在显示所有购物车商品的<table>中添加一个css绑定到“您保存 __%”消息:

样本代码:item016.htm

            <td data-bind='if: discount() > 0' style='color: red'>
              You saved <span data-bind='text: formattedDiscount,                      css: {supersaver: discount() > .15}'></span>!!!
            </td>

首先,您会注意到,通过用逗号分隔,可以向单个data-bind属性添加多个绑定。第二,css绑定以{supersaver: discount() > .15}对象为论据。这就像一个映射,定义了什么时候应该将一个 CSS 类添加到元素中。在这种情况下,只要产品的折扣大于 15%,就会增加.supersaver类,否则会删除。定义.supersaver规则的实际 CSS 可以在页面的任何地方定义(即外部或内部样式表)。

    .supersaver {
      font-size: 1.2em;
      font-weight: bold; }

如果你给第二个产品加 10%的折扣,你应该会看到我们的css绑定在起作用:

图 18:discount() > .15css绑定应用类

对象属性中包含的条件与ififnotvisible绑定的参数相同。它可以是属性、JavaScript 表达式或函数。

装帧风格

style绑定提供了与css绑定相同的功能,除了它操纵元素的style属性,而不是添加或移除类。由于内联样式需要键值对,因此该绑定参数的语法也略有不同:

              You saved <span data-bind='text: formattedDiscount,                      style: {fontWeight: discount() > .15 ? "bold" : "normal"}'></span>!!!

如果产品的折扣大于 15%,knockout. js 将把这个元素呈现如下:

            <td style='color: red; font-weight: bold'>

但是,如果低于 15%,就会有normalfont-weight。请注意,style绑定可以与元素现有的style属性结合使用。

属性绑定

attr绑定允许您使用视图模型属性动态定义 HTML 元素的属性。例如,如果我们的Product类有一个permalink属性,我们可以通过以下方式生成到各个产品页面的链接:

      <p><a data-bind='attr: {href: featuredProduct().permalink}'>View details</a></p>

这将向<a>标签添加一个href属性,指向存储在permalink属性中的任何内容。当然,如果permalink是一个可观测的,你可以利用 Denuke . js 的自动依赖跟踪的所有好处。由于永久链接通常与数据对象一起存储在永久存储器(例如,博客条目)中,因此以这种方式动态生成链接非常方便。

但是,attr绑定不仅仅是创建链接。它允许你在一个 HTML 元素中添加任何属性。这为将您的 knockout. js 模板与其他 DOM 库集成打开了各种各样的大门。

摘要

这一章介绍了 knockout. js 的外观绑定。当满足特定条件时,这些绑定中的许多会更改 HTML 元素。直接在绑定中定义这些条件是设计模板的一种直观方式,它将视图为中心的代码保持在视图模型之外。

请记住,knockout. js 的目标是通过在数据发生变化时自动同步视图,让您专注于应用背后的数据。一旦定义了绑定,就再也不用担心它们了(当然,除非您改变视图模型的结构)。

本章中展示的外观绑定提供了您需要的所有工具来显示您的数据,但是它们不允许我们向视图组件添加任何用户交互。在下一章中,我们将看一下 Dellow . js 是如何管理表单域的。