2017-01-25 3 views
2

Wie die Angular team (und mehrere blogs) beraten, versuche ich zu vermeiden, $rootScope wie möglich in meinen Apps zu verwenden.

$rootScope existiert, aber es kann mit globalen Variablen wie Sie $rootScope sparsam verwenden würde verwenden für das Böse eingesetzt werden (hoffentlich) in jeder Sprache

„Natürlich globalen Zustand saugt und Sie sollten Insbesondere nicht für Code verwenden, nur Daten.Wenn Sie versucht sind, eine Funktion auf $rootScope setzen, ist es fast immer besser, es in einen Dienst, der injiziert werden kann, wo es benötigt wird, und mehr leicht getestet. " - von Angular FAQ

Aber in einem meiner apps, verwende ich Ereignisse mehrmals wie $routeChangeStart die Broadcast Ereignisse mit $rootScope sind:

/* Force redirection to home page when a connected user calls login page */ 
$rootScope.$on("$routeChangeStart", function(event, next, current) { 
    if(next.$$route.originalPath == '/login' && Session.isUserConnected()) { 
     $location.path("/home"); 
    } 
} 

Ich sehe nicht, einen Weg zu Vermeiden Sie $rootScope in diesen Fällen.

  • Gibt es eine elegantere Art, diese Art von Tricks zu machen?
  • Ist das ein Designfehler meiner App, um es zu verwenden?
  • Muss ich mich damit abfinden, es zu benutzen, wenn es absolut notwendig ist?

Sag mir, wenn Sie wollen, dass ich mehr Code-Beispiele zur Verfügung zu stellen.

+0

Hast du diesen globalen Status gelesen und du solltest $ rootScope sparsam verwenden ??? –

+0

@RameshRajendran Ja, von der [ersten Link] (https://docs.angularjs.org/misc/faq) habe ich (letzten Absatz) zur Verfügung gestellt. Es ist aus der ** Angular Dokumentation FAQ **. – Mistalis

+0

Für diesen Fall hören Sie nur ein Ereignis, das an $ rootScope gesendet wird, ich denke, das ist ein gültiger Anwendungsfall. – Icycool

Antwort

0

Sie, dass missread. Zuerst wurde dieses Ereignis von Angular Team hinzugefügt - denken Sie, dass sie empfehlen, es nicht zu benutzen?: D Dieser Artikel besagt, dass Sie nicht alles auf $ rootScope setzen sollten, was ein einfacher Weg für Anfänger zu sein scheint.

Eigentlich mit $rootScope - für globale Ereignisse ist absolut in Ordnung - das ist der eigentliche Zweck dieses Dienstes.

+0

Ich frage mich, ob es "gute Praktiken" gibt, wie man diesen Code strukturiert (wie in $ rootScope, können Sie es überall schreiben), so dass es so klar und lesbar wie möglich bleibt – Mistalis

+0

"globale Dinge, die sind immer wahr ", sollte in app.run() sein. - (Weil es immer auf Ihrer App-Init ausgeführt wird) –

1

Wenn Sie nicht wollen, $rootScope in diesem Szenario yyou verwenden kann dies dies die mächtige resolve mit erreichen.

Da ich gesehen habe, dass Sie das ngRoute Modul verwenden, habe ich den Plunker und Code für ngRoute resolve.I erstellt, wenn Sie es auch für ui-router wollen.

Resolve Verwendung macht den Code schneller ausgeführt werden, da es nicht die DigestCycle unterziehen

Sie können die Benutzer-Flag aus dem Session.isUserConnected() erhalten, indem die Sitzung zu injizieren.

Dann können Sie diese Variable verwenden, um die Route umzuleiten.

// Code goes here 
 

 
angular.module('Test', ['ngRoute']) 
 
.config(function($routeProvider) { 
 
    var user = true; 
 
    //var user = Session.isUserConnected(); You can use your logic here 
 
    $routeProvider 
 
    .when("/login", { 
 
     template: "Login View", 
 
     resolve: { 
 
      
 
     data: function($q, $timeout,$location) { 
 
      var deferred = $q.defer(); 
 
      $timeout(function() { 
 
       
 
       if (user) { 
 
       $location.path("/home"); 
 
       deferred.reject(); 
 
       } else { 
 
       deferred.resolve(); 
 
       } 
 
      }); 
 
    
 
      return deferred.promise; 
 
      } 
 
     } 
 
    }) 
 
    .when("/home", { 
 
     template: "Home View. It is redirected from Login by checking the user condition. Without using the rootscope", 
 
     }) 
 
    .otherwise({redirectTo:'/login'}); 
 
}) 
 

 
    
 
<!DOCTYPE html> 
 
<html ng-app="Test"> 
 
    <head> 
 
    <link rel="stylesheet" href="style.css" /> 
 
    </head> 
 
    
 
    <body> 
 
    <div ng-view></div> 
 
    
 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js"></script> 
 
    <script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.js"></script> 
 
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-route.js"></script> 
 
    </body> 
 
</html>

Der Hauptteil geht hier:

data: function($q, $timeout, $location) { 
    var deferred = $q.defer(); 
    $timeout(function() { 
     if (user) { 
      $location.path("/home"); 
      deferred.reject(); 
     } else { 
      deferred.resolve(); 
     } 
    }); 
    return deferred.promise; 
} 

HERE IS A WORKING DEMO

+0

Interessante Sicht. In Bezug auf Leistung und Design, ist das besser als die Verwendung von '$ rootScope'? Denken Sie, dass ich ** es ** benutzen sollte, oder ist das nur ein Vorschlag von "wie anders zu machen"? – Mistalis

+0

Da eine Änderung in '$ rootScope' den Digest-Zyklus noch einmal ausführen wird und die Auflösungen nur einmal ausgeführt werden, während eine Route aufgerufen wird, ist die Auflösung im Vergleich zu '$ routeScope' möglicherweise besser, da Sie eine Alternative zu ' $ rootScope'. – Sravan

+0

@Mistalis, löst diese Antwort Ihr Problem? – Sravan

Verwandte Themen