Чому colspan не є відомим природним атрибутом у Angular 2?


80

Якщо ми спробуємо зробити такий код:

<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 виявляє цю невідповідність?

Відповіді:


115

** Подібний приклад <label for=...>

Властивість та атрибут не завжди 1: 1. Часто зустрічається прикладом є тег label

<label for="someId">

У кутовій

<label [for]="someId"> 

не вдається з тією ж помилкою, і вам потрібно буде прив’язати як

<label attr.for="{{someId}}">

або

<label [attr.for]="someId">

але

<label [htmlFor]="someId">

також буде працювати, оскільки в цьому випадку htmlForце властивість, яка відображається в forатрибуті DOM . Дивіться також https://developer.mozilla.org/de/docs/Web/API/HTMLLabelElement щодо htmlForвластивості (уProperties розділі)

Див. Також Яка різниця між атрибутом і властивістю?

colSpan фактична назва власності

Відповідно до https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableCellElement colSpan - це властивість, яка відображається в colspanатрибуті, тому (у верхньому регістрі S)

<td [colSpan]="1 + 1">Column</td>

Дивитися також https://plnkr.co/edit/BZelYOraELdprw5GMKPr?p=preview

працює просто чудово.

Чому Angular прив’язується до властивостей за замовчуванням

Кутова прив'язка до властивості за замовчуванням з міркувань продуктивності. Прив'язка до атрибута є дорогою, оскільки атрибути відображаються в DOM, і зміна DOM може призвести до переоцінки стилів CSS, які можуть збігатися після зміни, тоді як властивості - це лише значення в об'єкті JavaScript, який змінився.
З attr.Вами явно вибираєте дорогу поведінку.


2
Знання [attr.for] врятували мені день. Я витягнув волосся з помилкою "Неможливо прив'язати до 'contenteditable', оскільки це не відома властивість 'td'"
hirikarate

forповинен працювати зараз. Нещодавно був доданий псевдонім.
Günter Zöchbauer

1
Так само для розмаху рядків ... [attr.rowspan] = "4"
JOpuckman

1
Мені подобаються відповіді, де ви насправді отримуєте належну довідкову інформацію про те, чому деякі альтернативні рішення не обов’язково найкращий вибір.
Уілт

8

Моє питання полягає в тому, чому 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?
Shaiju T

4

Атрибути та властивості в Angular:

Коли браузер аналізує HTML, він створює в пам'яті представлення DOM аналізованого HTML. Те, що дані з атрибутів часто стають вихідними значеннями для властивостей, які присутні в DOM.

Оскільки colspan не є властивістю DOM, <td>але colSpan (велика літера S), вам доведеться використовувати властивість colSpan. Ось <td>елемент, показаний у chrome devtools:

введіть тут опис зображення

Ми бачимо, що атрибути html зберігаються у властивості DOM атрибута. Важливо розуміти, що поточний colspan відображається у властивості DOM colSpan, яке можна спостерігати нижче на зображенні.

Коли ви використовуєте прив'язку властивостей в Angular, ви зв'язуєте буквально 1 до 1 за допомогою цих властивостей DOM. Отже, для прив’язки до властивості colSpan нам потрібен такий синтаксис:

<td [colSpan]="1 + 1">Column</td>

Ми також можемо прив'язуватись безпосередньо до атрибутів у Angular, як ви зазначили з таким синтаксисом:

<td [attr.colspan]="1 + 1">Column</td>

Чому DOM виявляє цю невідповідність?

  1. З міркувань узгодженості всі властивості DOM мають нижню верблюдову оболонку
  2. Не всі атрибути можуть бути перетворені у властивості DOM способом 1 до 1. Візьмемо для прикладу атрибут class, на прикладі зображення ми бачимо, що атрибут class у нашому HTML приводить до 2 властивостей DOM ( classList, className).
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.