为啥 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】:

**类似的例子&lt;label for=...&gt;

属性和属性并不总是 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 时,它会在内存中创建解析后的 H​​TML 的 DOM 表示。来自属性的数据通常会成为 DOM 中存在的属性的初始值。

由于 colspan 不是 &lt;td&gt; 的 DOM 属性,但 colSpan(大写字母 S)是您必须使用 colSpan 属性的属性。这是 chrome devtools 中显示的 &lt;td&gt; 元素:

我们可以看到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 属性(classListclassName)。

【讨论】:

以上是关于为啥 colspan 在 Angular 2 中不是一个已知的原生属性?的主要内容,如果未能解决你的问题,请参考以下文章

为啥媒体查询在 Angular8 中不起作用

为啥我的“onclick()”事件在 Angular 中不起作用?

colSpan 和 row Span 如何添加到材料表 Header Angular 7?

反应colspan不起作用

一些赋值运算符在 AngularJS 表达式中不起作用.. 为啥不呢?

Angular 2 / 4 / 5 在 IE11 中不起作用