Różnica między $ scope i $ rootScope

91

Czy ktoś może wyjaśnić różnicę między $ scope i $ rootScope?

Myślę

$ scope:

Możemy uzyskać właściwości modelu ng w określonym kontrolerze z konkretnej strony, używając tego.


$ rootScope

Możemy uzyskać wszystkie właściwości modelu ng w dowolnym kontrolerze z dowolnej strony, używając tego.


Czy to jest poprawne? Albo coś innego?

Sergio Ivanuzzo
źródło
@Błąd kodu ! Co masz na myśli, ten link nie pomaga w moim pytaniu, jest $ zakres. $ Root, nie $ rootScope
$ rootScope znajduje się na szczycie hierarchii wszystkich zakresów w Twojej aplikacji kątowej.
Angad

Odpowiedzi:

88

„$ rootScope” jest obiektem nadrzędnym wszystkich obiektów kątowych „$ scope” utworzonych na stronie internetowej.

wprowadź opis obrazu tutaj

$ scope jest tworzony za pomocą, ng-controllerpodczas gdy $ rootscope jest tworzony za pomocą ng-app.

wprowadź opis obrazu tutaj

Aayushi Jain
źródło
69

Główną różnicą jest dostępność nieruchomości przypisanej do obiektu. Właściwość przypisana za $scopepomocą nie może być używana poza kontrolerem, w którym jest zdefiniowana, natomiast właściwość przypisana za pomocą $rootScopemoże być używana w dowolnym miejscu.

Przykład: Jeśli w poniższym przykładzie zamienić $rootScopez $scopewłasnością dział nie będzie wypełniana od pierwszego kontrolera w drugim

angular.module('example', [])
  .controller('GreetController', ['$scope', '$rootScope',
    function($scope, $rootScope) {
      $scope.name = 'World';
      $rootScope.department = 'Angular';
    }
  ])
  .controller('ListController', ['$scope',
    function($scope) {
      $scope.names = ['Igor', 'Misko', 'Vojta'];
    }
  ]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-app="example">
  <div class="show-scope-demo">
    <div ng-controller="GreetController">
      Hello {{name}}!
    </div>
    <div ng-controller="ListController">
      <ol>
        <li ng-repeat="name in names">{{name}} from {{department}}</li>
      </ol>
    </div>
  </div>
</body>

Ali Sadiq
źródło
18

Zgodnie z podręcznikiem programisty Angulara po zakresach :

Każda aplikacja Angular ma dokładnie jeden zakres główny, ale może mieć kilka zakresów podrzędnych. Aplikacja może mieć wiele zakresów, ponieważ niektóre dyrektywy tworzą nowe zakresy podrzędne (zapoznaj się z dokumentacją dyrektywy, aby zobaczyć, które dyrektywy tworzą nowe zakresy). Podczas tworzenia nowych zakresów są one dodawane jako elementy podrzędne zakresu nadrzędnego. Tworzy to strukturę drzewa, która jest analogiczna do modelu DOM, do którego są dołączone.

Zarówno administratorzy, jak i dyrektywy odnoszą się do zakresu, ale nie do siebie nawzajem. Taki układ izoluje kontroler od dyrektywy, a także od DOM. Jest to ważna kwestia, ponieważ sprawia, że ​​kontrolery widzą agnostyk, co znacznie poprawia historię testowania aplikacji.

Gary Stafford
źródło
13

$rootScopejest dostępny globalnie, bez względu na to, w jakim kontrolerze się znajdujesz, podczas gdy $scopejest dostępny tylko dla bieżącego kontrolera i jego elementów podrzędnych.

Tomek
źródło
3

W inny sposób możemy na to spojrzeć; $rootScopejest globalne, podczas gdy $scopejest lokalne. Kiedy Controllerjest przypisane do strony, więc $scopemożna tutaj użyć zmiennej, ponieważ jest ona powiązana z tym kontrolerem. Ale kiedy chcemy podzielić się jego wartością z innymi kontrolerami lub usługami, $rootScopejest on używany (** istnieją alternatywne sposoby, możemy udostępniać wartości, ale w tym przypadku chcemy użyć $rootScope).

Twoje drugie pytanie dotyczące tego, jak definiujesz te dwa słowa, jest poprawne.

Wreszcie trochę poza torem, używaj $rootScopeostrożnie. Podobnie do sposobu, w jaki używasz zmiennych globalnych, może być trudny do debugowania i możesz przypadkowo zmienić zmienną globalną gdzieś wewnątrz licznika czasu lub coś, co powoduje, że odczyt jest nieprawidłowy.

zrozumiałem
źródło
2

Zalecam przeczytanie oficjalnej szczegółowej dokumentacji Angulara dla lunet. Rozpocznij od sekcji „Hierarchie zakresu”:

https://docs.angularjs.org/guide/scope

Zasadniczo, $ rootScope i $ scope identyfikują określone części DOM, w ramach którego

  • Wykonywane są operacje kątowe
  • dostępne są zmienne zadeklarowane jako część $ rootScope lub $ scope

Wszystko, co należy do $ rootScope, jest dostępne globalnie w twojej aplikacji Angular, podczas gdy wszystko, co należy do $ scope, jest dostępne w części DOM, do której ma zastosowanie ten zakres.

$ RootScope jest stosowany do elementu DOM, który jest elementem głównym aplikacji Angular (stąd nazwa $ rootScope). Po dodaniu dyrektywy ng-app do elementu DOM, staje się ona głównym elementem DOM, w którym dostępny jest $ rootScope. Innymi słowy, właściwości itp. $ RootScope będą dostępne w całej aplikacji Angular.

Zakres Angular $ (i wszystkie jego zmienne i operacje) jest dostępny dla określonego podzbioru DOM w Twojej aplikacji. W szczególności zakres $ scope dla dowolnego konkretnego kontrolera jest dostępny dla części DOM, do której ten konkretny kontroler został zastosowany (przy użyciu dyrektywy ng-controller). Należy jednak zauważyć, że niektóre dyrektywy, np. Ng-powtórzenie, zastosowane w części DOM, w której zastosowano kontroler, mogą tworzyć zakresy potomne zakresu głównego - w ramach tego samego kontrolera - kontroler niekoniecznie zawiera tylko jeden zakres.

Jeśli spojrzysz na wygenerowany kod HTML po uruchomieniu aplikacji Angular, możesz łatwo zobaczyć, które elementy DOM „zawierają” zakres, ponieważ Angular dodaje klasę ng-scope do każdego elementu, do którego został zastosowany zakres (w tym element główny aplikacji, która ma $ rootScope).

Nawiasem mówiąc, znak '$' na początku $ scope i $ rootScope jest po prostu identyfikatorem w Angular dla rzeczy zarezerwowanych przez Angular.

Zauważ, że używanie $ rootScope do udostępniania zmiennych itp. Między modułami i kontrolerami nie jest ogólnie uważane za najlepszą praktykę. Deweloperzy JavaScript mówią o unikaniu „zanieczyszczenia” zasięgu globalnego poprzez udostępnianie tam zmiennych, ponieważ później mogą wystąpić konflikty, jeśli zmienna o tej samej nazwie zostanie użyta w innym miejscu, a deweloper nie zdaje sobie sprawy, że jest już zadeklarowana w $ rootScope. Znaczenie tego rośnie wraz z rozmiarem aplikacji i zespołem, który ją opracowuje. Idealnie byłoby, gdyby $ rootScope zawierało tylko stałe lub zmienne statyczne, które mają być zawsze spójne w całej aplikacji. Lepszym sposobem dzielenia się materiałami między modułami może być korzystanie z usług i fabryk, co jest innym tematem!

Chris Halcrow
źródło
2

Oba są obiektami skryptów Java, a różnicę ilustruje poniższy diagram.

wprowadź opis obrazu tutaj

NTB:
Pierwsza aplikacja kątowa próbuje znaleźć właściwość dowolnego modelu lub funkcji w $ scope, jeśli nie znalazła właściwości w $ scope, następnie wyszukuje w zakresie nadrzędnym w wyższej hierarchii. Jeśli właściwość nadal nie jest znaleziona w wyższej hierarchii, angular próbuje rozwiązać w $ rootscope.

Waqas Ahmed
źródło
1

Nowe style, takie jak AngularJS Styleguide Johna Papy , sugerują, że nie powinniśmy w ogóle używać $scopedo zapisywania właściwości bieżącej strony. Zamiast tego powinniśmy użyć controllerAs with vmpodejścia, w którym widok wiąże się z samym obiektem kontrolera. Następnie użyj do tego zmiennej przechwytywania, używając składni controllerAs. Wybierz spójną nazwę zmiennej, na przykład vm, co oznacza ViewModel.

Nadal będziesz jednak potrzebować $scopedo jego możliwości oglądania.

Stan
źródło