Какво е $scope в AngularJS? Урок с пример

⚡ Умно обобщение

$Scope в AngularJS е вграденият обект, който свързва контролер с неговия изглед. Тази страница обяснява създаването на обхват, функциите за поведение, йерархията на родител и дете, разликата от $rootScope и как digest циклизира обновяванията на обвързванията.

  • 🔗 Задължителна роля: $scope пренася променливи-членове от контролер в изгледа, така че шаблоните рендират данни, без да докосват директно DOM.
  • Функции на поведението: Прикачете функции към $scope, когато изгледът трябва да реагира на кликвания, промени във входните данни или други потребителски събития.
  • 🌳 Йерархия на обхвата: Директиви като ng-controller и ng-repeat създават дъщерни области (списъци), които отразяват DOM дървото на приложението.
  • ???? Обхват на $rootScope: За всяко приложение съществува един $rootScope, който се държи като глобален обект, който всеки дъщерен scope може да чете.
  • 🔍 Цикъл на смилане: $watch регистрира слушателите, $apply въвежда контекста на изпълнение на AngularJS, а $digest сравнява стойностите, докато моделът се стабилизира.
  • ???? Навик за изпълнение: Поддържайте изразите за наблюдение евтини, избягвайте достъп до DOM вътре в тях и извиквайте $destroy за области, които вече не са необходими.

Какво е $Scope в AngularJS

Какво е $scope в AngularJS?

$scope в AngularJS е вграден обект, който основно свързва „контролера“ и „изгледа“. Човек може да дефинира членски променливи в обхвата в рамките на контролера, които след това могат да бъдат достъпни от изгледа.

Всеки контролер в AngularJS приложението получава свой собствен екземпляр на $scope чрез инжектиране на зависимости. Всичко, което прикачите към този обект, става видимо за шаблона, управляван от контролера, така че $scope се държи като споделен модел на данни, който се намира между вашия JavaЛогика на скрипта и вашият HTML код за маркиране.

Разгледайте примера по-долу:

$scope в AngularJS

angular.module('app',[]).controller('HelloWorldCtrl',
	function($scope)
	{
		$scope.message = "Hello World"
	});

Code Обяснение:

  1. Името на модула е „приложение“
  2. Името на контролера е „HelloWorldCtrl“
  3. Scope object е основният обект, който се използва за предаване на информация от контролера към изгледа.
  4. Членска променлива е добавена към обект на обхват

⚠️ Предупреждение за синтаксис: - .controller() Методът приема два аргумента, името на контролера и фабричната функция, така че е необходима запетая между тях 'HelloWorldCtrl' намлява function($scope)Пропускането на запетая води до Uncaught SyntaxError преди AngularJS някога да се зареди с bootstrap.

Един контролер и един изглед са само половината от картината. Реалните приложения влагат контролери, повтарят списъци и използват повторно джаджи, което означава, че съществуват няколко области едновременно.

Как работят йерархията на обхвата и наследяването в 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 Обяснение:

  1. ParentCtrl определя siteName в собствения си обхват.
  2. ChildCtrl никога не определя siteName, но вътрешният div все още отпечатва Guru99 защото търсенето отива до родителския обхват.
  3. lesson се намира само в дъщерния обхват, така че родителският div не може да го прочете.

Кои директиви създават нов обхват?

  • ng-контролер: създава дъщерен обхват за елемента, върху който е поставен.
  • ng-повторение: създава един дъщерен обхват на итерация, поради което всеки ред може да съдържа различни стойности за един и същ израз.
  • Персонализирани директиви: може да поиска детски обхват или изолират обхват, който умишлено не наследява от родителя си.
  • Директиви на компонентите: всичко регистрирано в .component() Помощникът винаги получава изолиран обхват.

Тъй като дъщерните области се четат нагоре, разработчиците често се чудят къде се намира върхът на тази верига. Този обект от най-високо ниво се нарича $rootScope.

$scope срещу $rootScope: Каква е разликата?

AngularJS $rootScope е обхватът за цялото приложение. Едно приложение може да има само един $rootScope и той се използва като глобална променлива. Всеки $scope е дъщерен обхват, а $rootScope е родителят в горната част на дървото. Таблицата по-долу сравнява двата обекта.

Аспект $scope $rootScope
Брой инстанции на приложение Много, по един на контролер или директива за създаване на обхват Точно един
Създадено от Директиви като ng-controller и ng-repeat Инжекторът по време на първоначално зареждане на приложението
Видимост Неговият собствен елемент и всички наследници Всеки обхват в приложението
Типична употреба Данни и поведение за един изглед или един ред от списъка Стойности за цялото приложение, като например влязъл потребител
Основен риск Стойностите стават недостижими извън клона Колизии на имена и скрито свързване, като глобални променливи

Използвайте $rootScope пестеливо. Всичко, поставено там, е валидно за цялото приложение и е четливо навсякъде, така че споделената услуга обикновено е по-безопасен дом за глобално състояние. Официалният $rootScope препратка изброява пълния 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 Обяснение:

  1. Ние създаваме поведение, наречено „пълно име“. Това поведение е функция, която приема 2 параметъра (първо име, фамилия).
  2. След това поведението връща конкатенацията на тези 2 параметъра.
  3. В изгледа извикваме поведението и предаваме 2 стойности на „Guru„“ и „99“, които се предават като параметри на поведението.

Ако командата е изпълнена успешно, следният изход ще бъде показан, когато стартирате кода си в браузъра.

Изход:

Настройка или добавяне на поведение

В браузъра ще видите конкатенация на двете стойности на Guru & 99, които бяха предадени на поведението в регулатор.

Обвързвания като горното се обновяват сами и механизмът, който осъществява това, си струва да се разбере, преди приложението да стане голямо.

Защо Scope Watchers и Digest Cycle са важни

AngularJS поддържа изгледа в крак с обхвата чрез проверка „dirty checking“, а не чрез събития за промяна. Три API-та за обхват управляват този процес:

  • $гледай: регистрира слушател за израз. Интерполации като {{fullName}} регистрирайте наблюдатели вместо вас по време на свързването на шаблони.
  • $приложи: влиза в контекста на изпълнение на AngularJS, оценява вашия код и след това задейства дайджест. Необходим е само в рамките на персонализирани обратни извиквания на събития или обратни извиквания на библиотеки на трети страни, защото вградените директиви вече го извикват.
  • $дайджест: преглежда всеки наблюдател на $rootScope и неговите деца, сравнявайки текущата стойност с предишната и повтаряйки, докато моделът спре да се променя.

Тъй като дайджестът може да се изпълнява няколко пъти, изразите за наблюдение трябва да останат евтини. Избягвайте достъп до DOM вътре в тях, тъй като четенето на DOM е с порядъци по-бавно от четенето на JavaСвойство на скрипта.

Дълбочината на наблюдение също влияе върху цената. Наблюдението чрез препратка е най-бързото и забелязва само когато цялата стойност е заменена. $watchCollection забелязва добавени, премахнати или пренаредени елементи в масив или обект. Наблюдението по стойност обхожда вложена структура при всеки дайджест и е най-скъпият вариант, така че посягайте към него накрая.

Въпроси и Отговори

Изолираният обхват не наследява прототипно от родителския си обхват. Директивите на компонентите, изградени с помощника .component(), винаги получават такъв, което запазва многократно използваемите уиджети независими от заобикалящия контролер и блокира случайното четене на родителските свойства.

$emit изпраща събитие за обхват нагоре през родителските обхвати към $rootScope, докато $broadcast го изпраща надолу към всеки дъщерен обхват. И двата се получават с $on. Използвайте $broadcast пестеливо, защото той посещава всеки наследен обхват.

Извикайте scope.$destroy(), след като дъщерният scope вече не е необходим. Това спира разпространението на digest в scope-а и позволява на garbage collector-а да си възстанови моделите. Дерегистрирайте и ръчните наблюдатели, като извикате функцията, която $watch връща.

Асистенти като например Копилот на GitHub бързо генерират шаблонен код за обхват, но въпреки това издават грешки, като например липсваща запетая в регистрацията на контролера. Проверете всеки генериран фрагмент спрямо официалния Документация за обхвата на AngularJS.

AI асистентите картографират свойствата на $scope върху полетата на класа на компонента и пренаписват логиката на $watch като сигнали или RxJS потоци. Свържете ги с официалните ъглов документация и изпълнение на модулни тестове, тъй като генерираните реализации често пропускат наследени търсения на обхват.

Обобщете тази публикация с: