Улучшить эту документациюВыражения 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 не использует JavaScript's eval() для оценки выражений. Вместо этого служба $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, то выражение не выполняется и продолжает наблюдаться.
- Учитывая выражение, начинающееся с
::, когда входит цикл обработки и выражение проверяется на грязность, сохраните значение как 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–2018 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://code.angularjs.org/1.6.9/docs/guide/expression