Spec-Zone.ru › Angular.js 1.7

Улучшить эту статьюИнтерполяция и привязка данных

Разметка интерполяции с встроенными выражениями используется AngularJS для привязки данных к текстовым узлам и значениям атрибутов.

Пример интерполяции показан ниже:

<a ng-href="img/{{username}}.jpg">Hello {{username}}!</a>

Как работают привязки текста и атрибутов

Во время процесса компиляции компилятор использует $interpolate службу, чтобы определить, содержат ли текстовые узлы и атрибуты элементов разметку интерполяции со встроенными выражениями.

В случае наличия компилятор добавляет директиву interpolate к узлу и регистрирует наблюдения за вычисленной функцией интерполяции, которая будет обновлять соответствующие текстовые узлы или значения атрибутов как часть обычного цикла переваривания.

Обратите внимание, что директива interpolate имеет приоритет 100 и настраивает наблюдение в функции preLink.

Как вычисляется строковое представление

Если интерполированное значение не является String, оно вычисляется следующим образом:

  • undefined и null преобразуются в ''
  • если значение является объектом, который не является Number, Date или Array, $interpolate ищет пользовательскую функцию toString() в объекте и использует ее. Под пользовательской понимается функция, которая myObject.toString !== Object.prototype.toString.
  • если вышеперечисленное не применимо, используется JSON.stringify.

Привязка к булевым атрибутам

Атрибуты, такие как disabled, называются boolean атрибутами, потому что их наличие означает true, а их отсутствие означает false. Мы не можем использовать обычные привязки атрибутов с ними, потому что спецификация HTML не требует от браузеров сохранять значения булевых атрибутов. Это означает, что если мы поместим выражение AngularJS интерполяции в такой атрибут, то информация о привязке будет потеряна, потому что браузер игнорирует значение атрибута.

В следующем примере информация об интерполяции будет проигнорирована, и браузер просто интерпретирует атрибут как присутствующий, что означает, что кнопка всегда будет отключенной.

Disabled: <input type="checkbox" ng-model="isDisabled" />
<button disabled="{{isDisabled}}">Disabled</button>

По этой причине AngularJS предоставляет специальные директивы с префиксом ng для следующих булевых атрибутов: disabled, required, selected, checked, readOnly и open.

Эти директивы принимают выражение внутри атрибута и устанавливают соответствующий булев атрибут в значение true, когда выражение оценивается как истинное.

Disabled: <input type="checkbox" ng-model="isDisabled" />
<button ng-disabled="isDisabled">Disabled</button>

ngAttr для привязки к произвольным атрибутам

Веб-браузеры иногда бывают требовательны к тому, какие значения они считают допустимыми для атрибутов.

Например, рассмотрим этот шаблон:

<svg>
  <circle cx="{{cx}}"></circle>
</svg>

Мы ожидали бы, что AngularJS сможет привязаться к этому, но при проверке консоли мы видим что-то вроде Error: Invalid value for attribute cx="{{cx}}". Из-за ограничений API SVG DOM вы не можете просто написать cx="{{cx}}".

С ng-attr-cx вы можете обойти эту проблему.

Если атрибут с привязкой имеет префикс ngAttr (разъясняется как ng-attr-), то во время привязки он будет применен к соответствующему атрибуту без префикса. Это позволяет привязываться к атрибутам, которые в противном случае были бы обработанными браузерами (например, атрибуты circle[cx] элемента SVG). При использовании ngAttr, используется флаг allOrNothing службы $interpolate, поэтому, если какое-либо выражение в интерполированной строке приводит к значению undefined, атрибут удаляется и не добавляется к элементу.

Например, мы могли бы исправить пример выше, написав:

<svg>
  <circle ng-attr-cx="{{cx}}"></circle>
</svg>

Если необходимо изменить атрибут с верблюжьей нотацией (SVG-элементы имеют допустимые атрибуты с верблюжьей нотацией), например viewBox в элементе svg, можно использовать символ нижнего подчеркивания для обозначения того, что атрибут, к которому необходимо привязаться, имеет естественную верблюжью нотацию.

Например, для привязки к viewBox, мы можем написать:

<svg ng-attr-view_box="{{viewBox}}">
</svg>

Другие атрибуты также могут не работать как ожидается, когда они содержат разметку интерполяции, и могут быть использованы с ngAttr вместо этого. Ниже приведен список известных проблемных атрибутов:

  • size в элементах <select> (см. вопрос 1619)
  • placeholder в <textarea> в Internet Explorer 10/11 (см. вопрос 5025)
  • type в <button> в Internet Explorer 11 (см. вопрос 14117)
  • value в <progress> в Internet Explorer 11 (см. вопрос 7218)

Известные проблемы

Динамическое изменение интерполированного значения

Следует избегать динамического изменения содержимого интерполированной строки (например, значения атрибута или текстового узла). Ваши изменения, скорее всего, будут перезаписаны, когда исходная строка будет обработана. Это ограничение относится как к прямому изменению содержимого через JavaScript, так и к косвенному использованию директивы.

Например, не следует использовать интерполяцию в значении атрибута style (например, style="color: {{ 'orange' }}; font-weight: {{ 'bold' }};") и одновременно использовать директиву, которая изменяет содержимое этого атрибута, например ngStyle.

Встраивание разметки интерполяции внутри выражений

Примечание: Атрибуты директивы AngularJS принимают либо выражения или разметку интерполяции со встроенными выражениями. Считается неправильной практикой встраивать разметку интерполяции внутри выражения:
<div ng-show="form{{$index}}.$invalid"></div>

Вместо этого следует делегировать вычисление сложных выражений области видимости, как показано здесь:

<div ng-show="getForm($index).$invalid"></div>
function getForm(index) {
  return $scope['form' + index];
}

Вы также можете получить доступ к scope с помощью this в своих шаблонах:

<div ng-show="this['form' + $index].$invalid"></div>

Почему смешивание интерполяции и выражений является плохой практикой:

  • Это увеличивает сложность разметки
  • Нет гарантии, что это работает для каждой директивы, потому что сама интерполяция является директивой. Если другая директива получает доступ к данным атрибута до выполнения интерполяции, она получит исходную разметку интерполяции, а не данные.
  • Это влияет на производительность, так как интерполяция добавляет еще одно наблюдение в область видимости.
  • Поскольку это не рекомендуемое использование, мы не тестируем его, и изменения в ядре AngularJS могут сломать ваш код.

© 2010–2018 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://code.angularjs.org/1.7.8/docs/guide/interpolation

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API