前端编程里,property 和 attribute 是一对极容易混淆的术语。
Angular 的属性绑定语法:
<img [src]="itemImageUrl">
上例中括号里的 src,是 img element 的属性,也就是属性绑定的目标属性。所谓目标属性,就是我们期望进行赋值的 DOM 属性。
在 Angular 属性绑定的英文文档里,有这样一句话:
In most cases, the target name is the name of a property, even when it appears to be the name of an attribute.
在 Angular 的中文网站里,上面这句话的翻译为:
在大多数情况下,目标的名称就是 Property 的名称,哪怕它看起来像 Attribute 的名称。
可见,中文翻译保留了 Property 和 Attribute 的原文。
方括号使得其等号右边传入的值被当作一个动态表达式进行求值,结果赋给目标属性。如果不加中括号,等号右边的值被当成字符串字面量处理。
Property 和 Attribute 的区别?
以 colspan 和 colSpan 为例,前者是 attribute,后者是 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.
Angular 的 property binding 和 Interpolation 只能在 property 上工作,而不是 attribute.
colspan 是 td 的 attribute 名称,而不是 property.
上面的例子需要纠正成:
<!-- Notice the colSpan property is camel case -->
<tr><td [colSpan]="1 + 1">Three-Four</td></tr>
另一个例子:
<!-- Bind button disabled state to `isUnchanged` property -->
<button [disabled]="isUnchanged">Disabled Button</button>
Reflecting properties to attributes
HTML properties 将它们的值作为 HTML attribute 反映回 DOM 是很常见的。
看下面这段 JavaScript 代码:
div.id = 'my-id';
div.hidden = true;
当 div 元素的 id 或者 hidden property 发生变化时,
这些变化也会通过 HTML 属性实时地同步到 HTML 源代码里。
<div id="my-id" hidden>
这就是所谓的 Reflecting properties to attributes.
attribute 对于以声明方式配置元素也很有用,并且某些 API(如 Accessibility 和 CSS 选择器)依赖于 attribute 来工作。
在您希望元素的 DOM 表示与其 JavaScript 状态保持同步的任何地方,反射属性都非常有用。