Улучшить эту документациюВыражения AngularJS
Выражения AngularJS — это похожие на JavaScript фрагменты кода, которые в основном размещаются в интерполяционных связях, таких как <span title="{{ attrBinding }}">{{ textBinding }}</span>, но также используются непосредственно в атрибутах директивы, таких как ng-click="functionExpression()".
Например, следующие выражения допустимы в AngularJS:
1+2a+buser.nameitems[index]
Выражения AngularJS и JavaScript выражения
Выражения AngularJS похожи на JavaScript выражения, но с следующими отличиями:
-
Контекст: JavaScript выражения оцениваются относительно глобального
window. В AngularJS выражения оцениваются относительно объектаscope. -
Устойчивость к ошибкам: В JavaScript, попытка оценить неопределённое свойство вызывает
ReferenceErrorилиTypeError. В AngularJS, оценка выражения прощаетundefinedиnull. -
Фильтры: Вы можете использовать фильтры в выражениях для форматирования данных перед их отображением.
-
Отсутствуют операторы управления потоком: Вы не можете использовать следующие операторы в выражении AngularJS: условные операторы, циклы или исключения.
-
Отсутствуют объявления функций: Вы не можете объявлять функции в выражении AngularJS, даже внутри директивы
ng-init. -
Отсутствует создание регулярных выражений с использованием литеральной записи: Вы не можете создавать регулярные выражения в выражении AngularJS. Исключение из этого правила —
ng-pattern, который принимает допустимые регулярные выражения. -
Отсутствует оператор создания объектов с использованием оператора new: Вы не можете использовать оператор
newв выражении AngularJS. -
Отсутствуют побитовые, запятые и операторы void: Вы не можете использовать побитовые,
,илиvoidоператоры в выражении AngularJS.
Если вы хотите выполнить более сложный JavaScript-код, вы должны сделать его методом контроллера и вызвать метод из вашей разметки. Если вы хотите eval() выражение AngularJS самостоятельно, используйте метод $eval().
Вы можете попробовать оценить различные выражения здесь:
Контекст
AngularJS не использует eval() JavaScript для оценки выражений. Вместо этого служба $parse AngularJS обрабатывает эти выражения.
Выражения AngularJS не имеют прямого доступа к глобальным переменным, таким как window, document или location. Это ограничение является намеренным. Оно предотвращает случайный доступ к глобальному состоянию — распространённой причине скрытых ошибок.
Вместо этого используйте такие сервисы, как $window и $location в функциях контроллеров, которые затем вызываются из выражений. Такие сервисы предоставляют эмулируемый доступ к глобальным переменным.
Возможен доступ к объекту контекста с помощью идентификатора this и объекту локальных переменных с помощью идентификатора $locals.
Устойчивость к ошибкам
Оценка выражения устойчива к значениям undefined и null. В JavaScript, оценка a.b.c выбрасывает исключение, если a не является объектом. Хотя это имеет смысл для универсального языка программирования, оценка выражений в основном используется для привязки данных, которая часто выглядит так:
{{a.b.c}}
Более разумно показать ничего, чем выбросить исключение, если a не определено (возможно, мы ждём ответа от сервера, и оно скоро станет определённым). Если оценка выражений не была бы устойчивой к ошибкам, нам пришлось бы писать привязки, которые захламляли бы код, например: {{((a||{}).b||{}).c}}
Аналогично, вызов функции a.b.c() на undefined или null просто возвращает undefined.
Отсутствие операторов управления потоком
Помимо тернарного оператора (a ? b : c), вы не можете писать операторы управления потоком в выражении. Причина этого непосредственно связана с философией AngularJS, согласно которой логика приложения должна быть в контроллерах, а не в представлении. Если вам нужен реальный условный оператор, цикл или выброс из выражения в представлении, делегируйте эту задачу методу JavaScript.
Отсутствие объявлений функций или создания регулярных выражений с использованием литеральной записи
Вы не можете объявлять функции или создавать регулярные выражения внутри выражений AngularJS. Это делается для предотвращения сложной логики преобразования модели внутри шаблонов. Такая логика лучше размещается в контроллере или в специальном фильтре, где она может быть надлежащим образом протестирована.
$event
Директивы, такие как ngClick и ngFocus предоставляют объект $event в рамках области видимости этого выражения. Объект является экземпляром объекта события jQuery, если jQuery присутствует, или подобного объекта jqLite.
Обратите внимание в примере выше, как мы можем передать $event в clickMe, но как он не отображается в {{$event}}. Это происходит потому, что $event находится вне области видимости этой привязки.
Привязка один раз
Выражение, начинающееся с ::, считается выражением, привязываемым один раз. Выражения, привязываемые один раз, перестанут пересчитываться, как только они стабилизируются, что происходит после первого цикла обработки, если результат выражения — значение, отличное от undefined (см. алгоритм стабилизации значения ниже).
Причины использования однократной привязки
Основное назначение выражения однократной привязки — предоставить способ создания привязки, которая отменяется и высвобождает ресурсы, как только привязка стабилизируется. Уменьшение количества отслеживаемых выражений ускоряет цикл обработки и позволяет отображать больше информации одновременно.
Алгоритм стабилизации значения
Выражения однократной привязки сохранят значение выражения в конце цикла обработки, при условии, что это значение не undefined. Если значение выражения устанавливается внутри цикла обработки, а затем, в том же цикле, устанавливается в undefined, то выражение не выполняется и продолжает отслеживаться.
- Для выражения, начинающегося с
::, при входе в цикл обработки и проверке состояния выражения сохраните значение как V - Если V не undefined, отметьте результат выражения как стабильный и запланируйте задачу отмены отслеживания этого выражения при выходе из цикла обработки
- Обработайте цикл обработки как обычно
- По окончании цикла обработки и стабилизации всех значений обработайте очередь задач отмены отслеживания. Для каждой задачи отмены отслеживания, проверьте, сохраняется ли оно в значении, отличном от undefined. Если это так, отменяем отслеживание. В противном случае, продолжайте проверку состояния выражения в будущих циклах обработки, следуя тому же алгоритму, начиная с шага 1
Особый случай для литералов объектов
В отличие от простых значений, литералы объектов отслеживаются до тех пор, пока все ключи не будут определены. См. http://www.bennadel.com/blog/2760-one-time-data-bindings-for-object-literal-expressions-in-angularjs-1-3.htm
Как получить выгоду от однократной привязки
Если выражение не изменится после установки, оно является кандидатом на однократную привязку. Вот три примера случаев.
При интерполяции текста или атрибутов:
<div name="attr: {{::color}}">text: {{::name | uppercase}}</div>
При использовании директивы с двусторонней привязкой и параметрами, которые не будут меняться:
someModule.directive('someDirective', function() {
return {
scope: {
name: '=',
color: '@'
},
template: '{{name}}: {{color}}'
};
});
<div some-directive name="::myName" color="My color is {{::myColor}}"></div>
При использовании директивы, принимающей выражение:
<ul>
<li ng-repeat="item in ::items | orderBy:'name'">{{item.name}};</li>
</ul>
© 2010–2020 Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
https://code.angularjs.org/1.8.2/docs/guide/expression