Улучшить эту документациюВыражения Angular
Выражения Angular — это фрагменты кода, похожие на JavaScript, которые в основном размещаются в привязках интерполяции, таких как <span title="{{ attrBinding }}">{{ textBinding }}</span>, но также используются непосредственно в атрибутах директивы, таких как ng-click="functionExpression()".
Например, следующие выражения допустимы в Angular:
1+2a+buser.nameitems[index]
Выражения Angular по сравнению с выражениями JavaScript
Выражения Angular похожи на выражения JavaScript с следующими отличиями:
-
Контекст: Выражения JavaScript оцениваются относительно глобального
window. В Angular выражения оцениваются относительно объектаscope. -
Допустимость: В JavaScript попытка оценить неопределённое свойство порождает
ReferenceErrorилиTypeError. В Angular оценка выражения допускаетundefinedиnull. -
Фильтры: Вы можете использовать фильтры в выражениях для форматирования данных перед отображением.
-
Отсутствие операторов управления потоком: Вы не можете использовать следующие элементы в выражении Angular: условные операторы, циклы или исключения.
-
Отсутствие объявления функций: Вы не можете объявлять функции в выражении Angular, даже внутри директивы
ng-init. -
Отсутствие создания регулярных выражений с использованием литеральной записи: Вы не можете создавать регулярные выражения в выражении Angular.
-
Отсутствие создания объектов с оператором new: Вы не можете использовать оператор
newв выражении Angular. -
Отсутствие побитовых, запятых и void-операторов: Вы не можете использовать побитовые,
,илиvoidоператоры в выражении Angular.
Если вам нужно выполнить более сложный код JavaScript, сделайте его методом контроллера и вызовите метод из представления. Если вы хотите eval() выражение Angular самостоятельно, используйте метод $eval().
Вы можете попробовать оценить различные выражения здесь:
Контекст
Angular не использует механизм eval() JavaScript для оценки выражений. Вместо этого служба $parse Angular обрабатывает эти выражения.
Выражения Angular не имеют доступа к глобальным переменным, таким как window, document или location. Это ограничение намеренное. Оно предотвращает случайный доступ к глобальному состоянию — распространённому источнику скрытых ошибок.
Вместо этого используйте службы, такие как $window и $location в функциях, вызываемых из выражений. Такие службы обеспечивают эмулируемый доступ к глобальным переменным.
Можно получить доступ к объекту контекста с помощью идентификатора this и к объекту локальных переменных с помощью идентификатора $locals.
Допустимость
Оценка выражения допускает undefined и null. В JavaScript оценка a.b.c генерирует исключение, если a не является объектом. Хотя это имеет смысл для универсального языка программирования, оценка выражений в основном используется для привязки данных, которая часто выглядит так:
{{a.b.c}}
Более разумно ничего не отображать, чем генерировать исключение, если a не определено (возможно, мы ждём ответа от сервера, и оно скоро будет определено). Если оценка выражения не допускает undefined, нам пришлось бы писать привязки, которые загромождают код, например: {{((a||{}).b||{}).c}}
Аналогично, вызов функции a.b.c() на undefined или null просто возвращает undefined.
Отсутствие операторов управления потоком
Помимо условного оператора (a ? b : c), вы не можете писать операторы управления потоком в выражении. Причина этого заключается в основной философии Angular, согласно которой логика приложения должна быть в контроллерах, а не в представлениях. Если вам нужен настоящий условный оператор, цикл или вызов исключения из выражения представления, делегируйте эту задачу методу 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–2017 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://code.angularjs.org/1.5.11/docs/guide/expression