Что такое `$scope` в AngularJS? Учебное пособие с примером.
⚡ Умное резюме
В AngularJS `$Scope` — это встроенный объект, который связывает контроллер с его представлением. На этой странице объясняется создание области видимости, функции поведения, иерархия родительских и дочерних элементов, отличие от `$rootScope` и то, как циклы обновления (digest cycles) обновляют привязки.
Что такое $scope в AngularJS?
$scope в AngularJS — это встроенный объект, который по сути связывает «контроллер» и «представление». Можно определить переменные-члены в области действия внутри контроллера, к которым затем может получить доступ представление.
Каждый контроллер в AngularJS Приложение получает собственный экземпляр `$scope` через внедрение зависимостей. Всё, что вы прикрепляете к этому объекту, становится видимым для шаблона, управляемого контроллером, поэтому `$scope` ведёт себя как общая модель данных, которая находится между вашими компонентами. JavaЛогика скрипта и ваша HTML-разметка.
Рассмотрим пример ниже:
angular.module('app',[]).controller('HelloWorldCtrl', function($scope) { $scope.message = "Hello World" });
Code Объяснение:
- Имя модуля — «приложение».
- Имя контроллера — «HelloWorldCtrl».
- Объект Scope — это основной объект, который используется для передачи информации от контроллера к представлению.
- Переменная-член добавлена в объект области
⚠️ Синтаксическое предупреждение: .controller() Метод принимает два аргумента: имя контроллера и фабричную функцию, поэтому между ними должна быть запятая. 'HelloWorldCtrl' и function($scope)Отсутствие запятой приводит к ошибке. Uncaught SyntaxError до того, как AngularJS запустится.
Один контроллер и одно представление — это лишь половина картины. В реальных приложениях контроллеры вложены друг в друга, списки повторов повторяются, а виджеты используются повторно, что означает существование нескольких областей видимости одновременно.
Как работают иерархия областей видимости и наследование в AngularJS
Каждое приложение AngularJS имеет ровно одну корневую область видимости и может иметь любое количество дочерних областей видимости. Директивы создают эти дочерние области видимости и прикрепляют их к элементу DOM, который они декорируют, так что дерево областей видимости отражает структуру отображаемой страницы.
Когда AngularJS вычисляет такое выражение, как... {{siteName}}Сначала выполняется поиск этого свойства в области видимости, прикрепленной к элементу. Если свойство отсутствует, поиск переходит в родительскую область видимости и продолжается до тех пор, пока не достигнет корневой области видимости. JavaРазработчики скриптов знают это поведение как прототипное наследование, и дочерние области видимости наследуют от своих родителей именно таким образом.
В приведенном ниже примере один контроллер вложен в другой, что позволяет наблюдать за процессом наследования.
<div ng-app="scopeDemo"> <div ng-controller="ParentCtrl"> Parent scope value: {{siteName}} <div ng-controller="ChildCtrl"> Child reads parent value: {{siteName}} Child own value: {{lesson}} </div> </div> </div> <script type="text/javascript"> var app = angular.module("scopeDemo", []); app.controller("ParentCtrl", function($scope) { $scope.siteName = "Guru99"; }); app.controller("ChildCtrl", function($scope) { $scope.lesson = "AngularJS Scope"; }); </script>
Code Объяснение:
ParentCtrlопределяетsiteNameв рамках своей собственной сферы деятельности.ChildCtrlникогда не определяетsiteNameОднако внутренний div по-прежнему выводит сообщение. Guru99 потому что поиск обращается к родительской области видимости.lessonЭтот элемент существует только в дочерней области видимости, поэтому родительский div не может его прочитать.
Какие директивы создают новую область видимости?
- ng-controller: Создает дочернюю область видимости для элемента, на котором она размещена.
- ng-repeat: Создает одну дочернюю область видимости на каждую итерацию, поэтому каждая строка может содержать разные значения для одного и того же выражения.
- Пользовательские директивы: может запросить дочерний сегмент или изолировать Область видимости, которая намеренно не наследует от своего родителя.
- Директивы компонентов: все, что зарегистрировано в
.component()Вспомогательная функция всегда получает изолированную область видимости.
Поскольку дочерние области видимости считывают данные вверх, разработчики часто задаются вопросом, где находится вершина этой цепочки. Этот объект верхнего уровня называется $rootScope.
$scope против $rootScope: в чем разница?
AngularJS $rootScope $rootScope — это область видимости для всего приложения. В приложении может быть только один $rootScope, и он используется как глобальная переменная. Каждый $scope является дочерней областью видимости, а $rootScope — это родительский объект на вершине дерева. В таблице ниже приведено сравнение этих двух объектов.
| Аспект | $ scope | $rootScope |
|---|---|---|
| Количество экземпляров на одно приложение | Много, по одному на каждый контроллер или директиву, создающую область действия. | Ровно один |
| Созданный | Директивы, такие как ng-controller и ng-repeat | Инжектор во время загрузки приложения |
| Прозрачность | Его собственная стихия и все его потомки | Каждая область действия в приложении |
| Типичное использование | Данные и поведение для одного представления или одной строки списка. | Значения, характерные для всего приложения, например, информация о вошедшем в систему пользователе. |
| Основной риск | Значения становятся недоступными за пределами филиала. | Конфликты имен и скрытая взаимосвязь, как, например, в случае глобальных переменных. |
Используйте `$rootScope` с осторожностью. Всё, что там находится, существует на протяжении всего приложения и доступно для чтения повсюду, поэтому для глобального состояния обычно безопаснее использовать общий сервис. $rootScope reference Отображает полный список API.
Знание того, где хранятся данные, — это половина работы. Другая половина — это обучение системы тому, как реагировать на действия пользователя.
Настройка или добавление поведения в AngularJS
Чтобы реагировать на события или выполнять какие-либо вычисления/обработки в представлении, мы должны обеспечить поведение области видимости.
Поведения добавляются к объектам области действия для реагирования на определенные события, которые могут быть вызваны представлением. Как только поведение определено в контроллере, представление может получить к нему доступ.
Давайте посмотрим на примере, как мы можем этого добиться.
<!DOCTYPE html> <html lang="en"> <head> <meta chrset="UTF 8"> <title>Guru99</title> </head> <body ng-app="DemoApp"> <h1> Guru99 Global Event</h1> <script src="https://code.angularjs.org/1.6.9/angular.js"></script> <div ng-controller="DemoController"> {{fullName("Guru","99")}} </div> <script type="text/javascript"> var app = angular.module("DemoApp", []); app.controller("DemoController", function($scope) { $scope.fullName=function(firstName,lastname){ return firstName + lastname; } } ); </script> </body> </html>
Code Объяснение:
- Мы создаем поведение под названием «fullName». Это поведение представляет собой функцию, которая принимает 2 параметра (имя, фамилия).
- Затем поведение возвращает объединение этих двух параметров.
- В представлении мы вызываем поведение и передаем 2 значения типа «Guruи «99», которые передаются в качестве параметров в поведение.
Если команда выполнена успешно, при запуске кода в браузере будет отображен следующий вывод.
Выход:
В браузере вы увидите объединение обоих значений. Guru & 99, которые были переданы в поведение в контроллер.
Подобные привязки обновляются автоматически, и механизм, обеспечивающий этот процесс, стоит изучить, прежде чем приложение станет слишком большим.
Почему важны Scope Watchers и цикл дайджеста
AngularJS поддерживает соответствие представления области видимости с помощью проверки изменений (dirty check), а не через события изменения (change events). Этот процесс обеспечивают три API для областей видимости:
- $watch: Регистрирует слушателя для выражения. Интерполяции, такие как...
{{fullName}}регистрировать наблюдателей для вас во время связывания шаблонов. - $apply: Эта функция входит в контекст выполнения AngularJS, выполняет ваш код, а затем запускает дайджест. Она необходима только внутри пользовательских обработчиков событий или обработчиков событий сторонних библиотек, поскольку встроенные директивы уже вызывают её.
- $digest: Этот процесс обходит каждый наблюдатель в $rootScope и его дочерних элементах, сравнивая текущее значение с предыдущим, и повторяет это до тех пор, пока модель не перестанет меняться.
Поскольку дайджест может выполняться в несколько проходов, выражения наблюдения должны оставаться недорогими. Избегайте доступа к DOM внутри них, поскольку чтение DOM на порядки медленнее, чем чтение JavaСвойство скрипта.
Глубина запоминания также влияет на стоимость. Запоминание по эталонному значению — самый быстрый способ, и результат заметен только тогда, когда заменена вся величина. $watchCollection Отслеживание по значению позволяет отслеживать добавление, удаление или изменение порядка элементов внутри массива или объекта. Отслеживание по значению проходит по вложенной структуре при каждом обновлении и является наиболее ресурсоемким вариантом, поэтому используйте его в последнюю очередь.




