阅读(926) (0)

Angular 属性绑定

2022-06-28 10:41:41 更新

属性绑定

Angular 中的属性绑定可帮助你设置 HTML 元素或指令的属性值。使用属性绑定,可以执行诸如切换按钮、以编程方式设置路径,以及在组件之间共享值之类的功能。

包含本指南中的代码片段的工作示例,请参阅现场演练 / 下载范例

先决条件

为了充分理解属性绑定,你应该熟悉以下内容:

  • 组件基础
  • 模板基础
  • 绑定语法

了解数据流

属性绑定在单一方向上将值从组件的属性送到目标元素的属性。

绑定到属性

要绑定到元素的属性,请将其括在方括号 ​[]​ 内,该括号会将属性标为目标属性。目标属性就是你要对其进行赋值的 DOM 属性。例如,以下代码中的目标属性是 img 元素的 ​src ​属性。

<img [src]="itemImageUrl">

在大多数情况下,目标的名称就是 Property 的名称,哪怕它看起来像 Attribute 的名称。在这个例子中,​src ​就是 ​<img>​ 元素的 Property 名称。

方括号 ​[]​ 使 Angular 将等号的右侧看作动态表达式进行求值。如果不使用方括号,Angular 就会将右侧视为字符串字面量并将此属性设置为该静态值。

<app-item-detail childItem="parentItem"></app-item-detail>

省略方括号就会渲染出字符串 ​parentItem​,而不是 ​parentItem ​的值。

将元素的属性设置为组件属性的值

要将 ​<img>​ 的 ​src ​属性绑定到组件的属性,请将目标 ​src ​放在方括号中,后跟等号,然后是组件的属性。在这里组件的属性是 ​itemImageUrl​。

<img [src]="itemImageUrl">

在组件类 ​AppComponent ​中声明 ​itemImageUrl ​属性。

itemImageUrl = '../assets/phone.png';

colspan 和 colSpan

最容易混淆的地方是 ​colspan ​这个 Attribute 和 ​colSpan ​这个 Property。请注意,这两个名称只有一个字母的大小写不同。

如果你这样写:

<tr><td colspan="{{1 + 1}}">Three-Four</td></tr>

你会收到此错误:

Template parse errors:
Can't bind to 'colspan' because it isn't a known built-in property

如消息中所示,​<td>​ 元素没有 ​colspan ​Property。这是正确的,因为 ​colspan ​是一个 Attribute — ​colSpan​(带大写 ​S​)才是相应的 Property。插值和 Property 绑定只能设置 Property,不能设置 Attribute。

相反,你应该使用 Property 绑定并将其编写为:

<!-- Notice the colSpan property is camel case -->
<tr><td [colSpan]="1 + 1">Three-Four</td></tr>

另一个示例是在组件说它自己 ​isUnchanged ​时禁用按钮:

<!-- Bind button disabled state to `isUnchanged` property -->
<button [disabled]="isUnchanged">Disabled Button</button>

另一个是设置指令的属性:

<p [ngClass]="classes">[ngClass] binding to the classes property making this blue</p>

还有一个是设置自定义组件的模型属性,这是父组件和子组件进行通信的一种好办法:

<app-item-detail [childItem]="parentItem"></app-item-detail>

切换按钮功能

若要根据布尔值禁用按钮的功能,请将 DOM 的 ​disabled ​Property 设置为类中的源属性(可能为 ​true ​或 ​false​)。

<!-- Bind button disabled state to `isUnchanged` property -->
<button [disabled]="isUnchanged">Disabled Button</button>

由于 ​AppComponent ​中属性 ​isUnchanged ​的值是 ​true​,Angular 会禁用该按钮。

isUnchanged = true;

设置指令的属性

要设置指令的属性,请将指令放在方括号中,例如 ​[ngClass]​,后跟等号和一个源属性。在这里,这个源属性的值是 ​classes ​。

<p [ngClass]="classes">[ngClass] binding to the classes property making this blue</p>

要使用该属性,必须在组件类中声明它,在这里是 ​AppComponent​。其 ​classes ​的值是 ​special ​。

classes = 'special';

Angular 会将 ​special ​类应用到 ​<p>​ 元素,以便你可以通过 ​special ​来应用 CSS 样式。

在组件之间绑定值

要设置自定义组件的模型属性,请将目标属性(此处为 ​childItem​)放在方括号 ​[]​ 中,其后跟着等号与源属性。在这里,这个源属性是 ​parentItem ​。

<app-item-detail [childItem]="parentItem"></app-item-detail>

要使用目标和源属性,必须在它们各自的类中声明它们。

在组件类(这里是 ​ItemDetailComponent​)中声明 ​childItem ​的目标。

例如,以下代码在其组件类(这里是 ​ItemDetailComponent​)中声明了 ​childItem ​的目标。

然后,代码包含一个带有 ​@Input()​ 装饰器的 ​childItem ​属性,这样才能让数据流入其中。

@Input() childItem = '';

接下来,代码在其组件类(这里是 ​AppComponent​)中声明属性 ​parentItem​。在这个例子中, ​childItem ​的类型为 ​string ​,因此 ​parentItem ​也必须为字符串。在这里,​parentItem ​的字符串值为 ​lamp​。

parentItem = 'lamp';

这种配置方式下,​<app-item-detail>​ 的视图使用来自 ​childItem ​的值 ​lamp​。

属性绑定与安全性

属性绑定可以帮助确保内容的安全。例如,考虑以下恶意内容。

evilTitle = 'Template <script>alert("evil never sleeps")</script> Syntax';

组件模板对内容进行插值,如下所示:

<p><span>"{{evilTitle}}" is the <i>interpolated</i> evil title.</span></p>

浏览器不会处理 HTML,而是原样显示它,如下所示。

"Template <script>alert("evil never sleeps")</script> Syntax" is the interpolated evil title.

Angular 不允许带有 ​<script>​ 标记的 HTML,既不能用于插值也不能用于属性绑定,这样就会阻止运行 JavaScript。

但是,在以下示例中,Angular 在显示值之前会先对它们进行无害化处理。

<!--
 Angular generates a warning for the following line as it sanitizes them
 WARNING: sanitizing HTML stripped some content (see https://g.co/ng/security#xss).
-->
 <p>"<span [innerHTML]="evilTitle"></span>" is the <i>property bound</i> evil title.</p>

插值处理 ​<script>​ 标记的方式与属性绑定的方式不同,但这两种方法都可以使内容无害。以下是经过无害化处理的 ​evilTitle ​示例的浏览器输出。

"Template Syntax" is the property bound evil title.

属性绑定和插值

通常,插值和属性绑定可以达到相同的结果。以下绑定会做相同的事。

<p><img src="{{itemImageUrl}}"> is the <i>interpolated</i> image.</p>
<p><img [src]="itemImageUrl"> is the <i>property bound</i> image.</p>

<p><span>"{{interpolationTitle}}" is the <i>interpolated</i> title.</span></p>
<p>"<span [innerHTML]="propertyTitle"></span>" is the <i>property bound</i> title.</p>

将数据值渲染为字符串时,可以使用任一种形式,只是插值形式更易读。但是,要将元素属性设置为非字符串数据值时,必须使用属性绑定。