为啥 colspan 在 Angular 2 中不是一个已知的原生属性?
Posted
技术标签:
【中文标题】为啥 colspan 在 Angular 2 中不是一个已知的原生属性?【英文标题】:Why is colspan not a known native attribute in Angular 2?为什么 colspan 在 Angular 2 中不是一个已知的原生属性? 【发布时间】:2016-06-07 13:05:38 【问题描述】:如果我们尝试这样的代码:
<td [colspan]="1 + 1">Column</td>
或者这个:
<td colspan="1 + 1">Column</td>
我们很快发现“colspan
不是已知的原生属性。”
从 A2 文档中我们了解到:
该元素没有 colspan 属性。它有“colspan”属性,但是插值和属性绑定只能设置属性,不能设置属性。
我们必须这样做:
<td [attr.colspan]="1 + 1">Column</td>
这很公平。
问题:
我的问题是,为什么colspan
不是 DOM 的属性,如果缺少它,浏览器怎么可能渲染表格,因为浏览器渲染的是 DOM 而不是 html?
另外,如果我打开 Chrome 检查器并转到属性选项卡,为什么我可以将 colspan 视为元素的属性?
为什么 DOM 会出现这种不一致?
【问题讨论】:
【参考方案1】:我的问题是,为什么 colspan 不是 DOM 的属性,如果它 缺少,浏览器怎么可能呈现表格,因为 浏览器渲染 DOM 而不是 HTML?
Colspan 是 DOM 的一个属性,但它不是一个属性,所以它是只读的,浏览器会渲染它,因为它是一个属性。
另外,如果我打开 Chrome 检查器并转到属性选项卡,为什么我可以将 colspan 视为元素的属性?
当您检查时,镶边会显示属性和属性。
如果你考虑关注,
<html>
<head>
</head>
<body>
<table>
<tr><th>A</th><th>A</th></tr>
<tr><td colspan="2" id="xyz">B</td></tr>
</table>
</body>
</html>
document.getElementById('xyz').colspan
导致undefined
因为它不是属性
but document.getElementById('xyz').id
导致xyz
因为它是一个属性
【讨论】:
chrome 同时显示属性和属性,这是 chrome 的错误吗?【参考方案2】:**类似的例子<label for=...>
属性和属性并不总是 1:1。一个经常遇到的例子是标签标签
<label for="someId">
在 Angular 中
<label [for]="someId">
失败并出现同样的错误,你需要像这样绑定
<label attr.for="someId">
或
<label [attr.for]="someId">
但是
<label [htmlFor]="someId">
也可以,因为在这种情况下,htmlFor
是反映到 DOM for
属性的属性。
另请参阅 https://developer.mozilla.org/de/docs/Web/API/HTMLLabelElement 以获取 htmlFor
属性(在 Properties
部分中)
另见What is the difference between attribute and property?
colSpan
实际属性名
根据https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableCellElementcolSpan
是反映到colspan
属性的属性,因此(大写S
)
<td [colSpan]="1 + 1">Column</td>
另见https://plnkr.co/edit/BZelYOraELdprw5GMKPr?p=preview
工作得很好。
为什么 Angular 默认绑定属性
出于性能原因,Angular 默认绑定到该属性。绑定到属性的成本很高,因为属性会反映在 DOM 中,并且 DOM 中的更改会导致重新评估更改后可能匹配的 CSS 样式,而属性只是 javascript 对象中发生更改的值。
使用attr.
,您可以明确选择接受代价高昂的行为。
【讨论】:
[attr.for] 的知识拯救了我的一天。我拉头发时出现错误“无法绑定到 'contenteditable',因为它不是 'td' 的已知属性”for
现在应该可以工作了。最近添加了一个别名。
行跨度同上... [attr.rowspan]="4"
我喜欢这样的答案,您实际上可以获得一些正确的背景信息,说明为什么某些 alternative solutions 不一定是最佳选择。【参考方案3】:
Angular 中的属性和属性:
当浏览器解析 HTML 时,它会在内存中创建解析后的 HTML 的 DOM 表示。来自属性的数据通常会成为 DOM 中存在的属性的初始值。
由于 colspan 不是 <td>
的 DOM 属性,但 colSpan(大写字母 S)是您必须使用 colSpan 属性的属性。这是 chrome devtools 中显示的 <td>
元素:
我们可以看到html属性保存在属性DOM属性中。重要的是要意识到当前的 colspan 反映在 DOM colSpan 属性中,可以在下面的图像中观察到。
当您在 Angular 中使用属性绑定时,您实际上是在将这些 DOM 属性一对一地绑定。因此,为了绑定到 colSpan 属性,我们需要以下语法:
<td [colSpan]="1 + 1">Column</td>
我们还可以直接绑定到 Angular 中的属性,正如您使用以下语法指出的那样:
<td [attr.colspan]="1 + 1">Column</td>
为什么 DOM 会出现这种不一致?
-
出于一致性原因,所有 DOM 属性都采用驼峰式大小写
并非所有属性都可以以一对一的方式转换为 DOM 属性。以 class 属性为例,我们可以在示例图像中看到 HTML 中的 class 属性导致 2 个 DOM 属性(
classList
、className
)。
【讨论】:
以上是关于为啥 colspan 在 Angular 2 中不是一个已知的原生属性?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的“onclick()”事件在 Angular 中不起作用?
colSpan 和 row Span 如何添加到材料表 Header Angular 7?