Улучшить эту документациюВыражения 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 не использует JavaScript's eval() для вычисления выражений. Вместо этого служба $parse Angular обрабатывает эти выражения.
Выражения Angular не имеют доступа к глобальным переменным, таким как window, document или location. Это ограничение намеренное. Оно предотвращает случайный доступ к глобальному состоянию — распространённому источнику скрытых ошибок.
Вместо этого используйте службы, такие как $window и $location в функциях, вызываемых из выражений. Такие службы предоставляют эмулируемый доступ к глобальным переменным.
Универсальность
Вычисление выражений терпимо к значениям undefined и null. В JavaScript оценка a.b.c вызывает исключение, если a не является объектом. Хотя это имеет смысл для универсального языка, вычисления выражений в основном используются для привязки данных, которая часто выглядит так:
{{a.b.c}}
Более разумно показать ничего, чем вызывать исключение, если a не определено (возможно, мы ждём ответа сервера, и оно скоро станет определённым). Если вычисление выражений не было бы универсальным, нам пришлось бы писать привязки, которые загромождали бы код, например: {{((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, то выражение не выполняется и продолжает следить.
- Данное выражение, начинающееся с
::, при входе в цикл обработки и проверке, если выражение грязное, сохраняет значение как 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.4.14/docs/guide/expression