Unterschied zwischen $ scope und $ rootScope

89

Kann jemand den Unterschied zwischen $ scope und $ rootScope erklären?

Meiner Ansicht nach

$ scope:

Auf diese Weise können wir ng-Modelleigenschaften in einem bestimmten Controller von der jeweiligen Seite abrufen.


$ rootScope

Auf diese Weise können wir alle ng-Modelleigenschaften in jedem Controller von jeder Seite abrufen.


Ist das richtig? Oder sonst noch etwas?

Sergio Ivanuzzo
quelle
@Code Fehler ! Was du meinst, dieser Link hilft nicht bei meiner Frage, es gibt $ scope. $ Root, kein $ rootScope
$ rootScope steht in Ihrer Winkel-App ganz oben in der Hierarchie aller Bereiche.
Angad

Antworten:

86

"$ rootScope" ist ein übergeordnetes Objekt aller auf einer Webseite erstellten "$ scope" -Winkelobjekte.

Geben Sie hier die Bildbeschreibung ein

$ scope wird mit erstellt, ng-controllerwährend $ Rootscope mit erstellt wird ng-app.

Geben Sie hier die Bildbeschreibung ein

Aayushi Jain
quelle
66

Der Hauptunterschied ist die Verfügbarkeit der dem Objekt zugewiesenen Eigenschaft. Eine mit zugewiesene Eigenschaft $scopekann nicht außerhalb des Controllers verwendet werden, in dem sie definiert ist, während eine mit zugewiesene Eigenschaft verwendet werden kann$rootScope überall verwendet werden kann.

Beispiel: Wenn im Beispiel unten Sie ersetzen $rootScopemit $scopeder Abteilung Eigenschaft wird nicht von der ersten Steuerung in dem zweiten bestückt werden

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
quelle
18

Laut Angulars Entwicklerhandbuch für Bereiche :

Jede Angular-Anwendung hat genau einen Stammbereich, kann jedoch mehrere untergeordnete Bereiche haben. Die Anwendung kann mehrere Bereiche haben, da einige Anweisungen neue untergeordnete Bereiche erstellen (Informationen dazu, welche Anweisungen neue Bereiche erstellen, finden Sie in der Direktivendokumentation). Wenn neue Bereiche erstellt werden, werden sie als untergeordnete Bereiche ihres übergeordneten Bereichs hinzugefügt. Dadurch wird eine Baumstruktur erstellt, die dem DOM entspricht, an dem sie angehängt sind.

Sowohl Controller als auch Direktiven beziehen sich auf den Geltungsbereich, jedoch nicht aufeinander. Diese Anordnung isoliert den Controller sowohl von der Direktive als auch vom DOM. Dies ist ein wichtiger Punkt, da die Controller dadurch agnostisch angezeigt werden, was die Testgeschichte der Anwendungen erheblich verbessert.

Gary Stafford
quelle
13

$rootScopeist global verfügbar, unabhängig davon, in welchem ​​Controller Sie sich befinden, während $scopees nur für den aktuellen Controller und seine untergeordneten Controller verfügbar ist.

Tom
quelle
3

Auf andere Weise können wir dies betrachten; $rootScopeist global, während $scopelokal ist. Wenn Controllereiner Seite zugewiesen wird, $scopekann hier eine Variable verwendet werden, da sie an diesen Controller gebunden ist. Wenn wir jedoch den Wert für andere Controller oder Dienste freigeben möchten, $rootScopewird dieser verwendet (** Es gibt alternative Möglichkeiten, wir können Werte für mehrere Benutzer freigeben, in diesem Fall möchten wir ihn jedoch verwenden $rootScope).

Ihre zweite Frage, wie Sie diese beiden Wörter definieren, ist richtig.

Zuletzt etwas abseits der Strecke, bitte vorsichtig verwenden $rootScope. Ähnlich wie bei der Verwendung globaler Variablen kann das Debuggen schwierig sein, und Sie können die globale Variable versehentlich irgendwo in einem Timer ändern oder etwas, das Ihre Lesung falsch macht.

Roger
quelle
2

Jede Anwendung hat mindestens ein einziges rootScope und ihr Lebenszyklus ist der gleiche wie der der App. Jeder Controller kann seinen eigenen Bereich haben, der nicht mit anderen geteilt wird.

Schauen Sie sich diesen Artikel an:

https://github.com/angular/angular.js/wiki/Understanding-Scopes

User_allowed
quelle
2

Ich empfehle Ihnen, die offizielle ausführliche Angular-Dokumentation für Bereiche zu lesen. Beginnen Sie mit dem Abschnitt 'Umfangshierarchien':

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

Im Wesentlichen identifizieren sowohl $ rootScope als auch $ scope bestimmte Teile des DOM, in denen

  • Winkeloperationen werden ausgeführt
  • Variablen, die als Teil des Bereichs $ rootScope oder $ deklariert sind, sind verfügbar

Alles, was zu $ ​​rootScope gehört, ist global in Ihrer Angular-App verfügbar, während alles, was zu einem $ scope gehört, in dem Teil des DOM verfügbar ist, für den dieser Bereich gilt.

Das $ rootScope wird auf das DOM-Element angewendet, das das Root-Element für die Angular-App ist (daher der Name $ rootScope). Wenn Sie die Anweisung ng-app zu einem Element des DOM hinzufügen, wird dies zum Stammelement des DOM, in dem $ rootScope verfügbar ist. Mit anderen Worten, Eigenschaften usw. von $ rootScope sind in Ihrer gesamten Angular-Anwendung verfügbar.

Ein Angular $ -Bereich (und alle seine Variablen und Operationen) steht einer bestimmten Teilmenge des DOM in Ihrer Anwendung zur Verfügung. Insbesondere steht der $ scope für einen bestimmten Controller für den Teil des DOM zur Verfügung, auf den dieser bestimmte Controller angewendet wurde (unter Verwendung der ng-controller-Direktive). Beachten Sie jedoch, dass bestimmte Anweisungen, z. B. ng-repeat, bei Anwendung in einem Teil des DOM, in dem der Controller angewendet wurde, untergeordnete Bereiche des Hauptbereichs erstellen können - innerhalb desselben Controllers - ein Controller enthält nicht unbedingt nur einen Bereich.

Wenn Sie sich beim Ausführen Ihrer Angular-App den generierten HTML-Code ansehen, können Sie leicht erkennen, welche DOM-Elemente einen Bereich enthalten, da Angular die Klasse ng-scope für jedes Element hinzufügt, auf das ein Bereich angewendet wurde (einschließlich des Stammelements) der App, die das $ rootScope hat).

Übrigens ist das '$'-Zeichen am Anfang von $ scope und $ rootScope einfach eine Kennung in Angular für Dinge, die von Angular reserviert wurden.

Beachten Sie, dass die Verwendung von $ rootScope zum Teilen von Variablen usw. zwischen Modulen und Controllern im Allgemeinen nicht als bewährte Methode angesehen wird. JavaScript-Entwickler sprechen davon, die Verschmutzung des globalen Bereichs durch die gemeinsame Nutzung von Variablen zu vermeiden, da es später zu Konflikten kommen kann, wenn eine gleichnamige Variable an einer anderen Stelle verwendet wird, ohne dass der Entwickler merkt, dass sie bereits im $ rootScope deklariert ist. Die Bedeutung dieser Anwendung steigt mit der Größe der Anwendung und dem Team, das sie entwickelt. Im Idealfall enthält $ rootScope nur Konstanten oder statische Variablen, die in der gesamten App jederzeit konsistent sein sollen. Eine bessere Möglichkeit, Inhalte modulübergreifend zu teilen, ist möglicherweise die Verwendung von Diensten und Fabriken, was ein weiteres Thema ist!

Chris Halcrow
quelle
2

Beide sind Java-Skriptobjekte und der Unterschied wird durch das folgende Diagramm dargestellt.

Geben Sie hier die Bildbeschreibung ein

NTB: Die
erste Winkelanwendung versucht, die Eigenschaft eines Modells oder einer Funktion in $ scope zu finden. Wenn die Eigenschaft in $ scope nicht gefunden wird, sucht sie im übergeordneten Bereich in der oberen Hierarchie. Wenn die Eigenschaft immer noch nicht in der oberen Hierarchie gefunden wird, versucht Angular, in $ Rootscope aufzulösen.

Waqas Ahmed
quelle
1

Neue Stile wie John Papas AngularJS Styleguide schlagen vor, dass wir $scopedie Eigenschaften der aktuellen Seite überhaupt nicht speichern sollten . Stattdessen sollten wir den controllerAs with vmAnsatz verwenden, bei dem die Ansicht an das Controller-Objekt selbst gebunden ist. Verwenden Sie dazu eine Capture-Variable, wenn Sie die ControllerAs-Syntax verwenden. Wählen Sie einen konsistenten Variablennamen wie vm, der für ViewModel steht.

Sie benötigen das jedoch weiterhin $scopefür die Überwachungsfunktionen.

Stan
quelle