2017-02-16 2 views
0

Meine eckige Anwendung ist in 4 Module unterteilt und alle Module erfordern Benutzerdetails, so dass ich GetUser-Methode von jedem der Module aufrufen. Wenn also meine Anwendung alle 4 Module lädt, wird die getUser-API gleichzeitig ausgeführt, was zu 4 get-Anfragen auf dem Server führt. Wie kann ich das verhindern? Ich benutze Singleton-Muster in meiner getUser-Methode. Sobald mein Benutzer geladen ist, dient er einfach dem Benutzer von einem Objekt. Aber das löst das Problem nicht, wenn alle Module gleichzeitig nach dem Benutzer fragen.Handle simultan erhalten Anrufe in angularjs

Mein Code sieht wie folgt aus

getUser() { 
let defer = this.q.defer(); 

if (!this.user) { 
    this.http.get(`${this.config.apiHost}users`) 
     .success(result => { 
      this.user = result; 

      this.rootScope.$broadcast('userFound', this.user); 
      defer.resolve(this.user); 
     }) 
     .error(err => defer.reject(err)) 
} 
else { 
    defer.resolve(this.user); 
    this.rootScope.$broadcast('userFound', this.user); 
} 
return defer.promise; 
} 
+0

Fügen Sie den Anruf in einem Dienst hinzu. Der Dienst prüft, ob das Benutzerobjekt existiert. Wenn dies der Fall ist, gibt es das Objekt zurück - Wenn nicht, gib den get-Aufruf zurück. ** ODER ** Sie können den Anruf zwischenspeichern – Weedoze

+0

Ich habe bereits die Methode nur im Dienst definiert und überprüft, ob das Benutzerobjekt existiert oder nicht. Aber wenn alle Module versuchen, den Benutzer gleichzeitig zu bekommen, funktioniert dieser Ansatz nicht. –

+0

verwenden Sie UI-Router? .. Ich kann Ihnen vorschlagen, eine Auflösungsmethode im Routing zu verwenden und das Ergebnis der Anfrage an Ihren Controller zu übergeben. –

Antwort

1

Durch die aktuelle Anfrage in einer Variablen zu speichern, den Anruf zu UserService.get die gleiche Anfrage Versprechen zurück.

Dann, wenn das Versprechen verrechnet wird, wird es auf alle Ihre Module auflösen.

angular.module('app').service('UserService', function ($http) { 

    var self = this; 

    var getRequestCache; 

    /** 
    * Will get the current logged in user 
    * @return user 
    */ 
    this.get = function() { 
     if (getRequestCache) { 
      return getRequestCache; 
     } 

     getRequestCache = $http({ 
      url: '/api/user', 
      method: 'GET', 
      cache: false 
     }).then(function (response) { 
      // clear request cache when request is done so that a new request can be called next time 
      getRequestCache = undefined; 
      return response.data; 
     }); 

     return getRequestCache; 
    }; 

}); 
0

Sie verwenden ui-router für das Routing. Sie können dies verwenden, um den Benutzer bei der Landung auf der Seite aufzulösen.

In Ihrem Routing-config:

$stateProvider 
    .state('myPage', { 
     url: '/myPage', 
     templateUrl: 'myPage.html', 
     controller: 'myCtrl', 
     resolve: { 
      userDetails: ['UserService', function(UserService) { 
       return UserService.getUserDetails(); 
      }], 
     } 
    }) 

In Ihrem Controller

angular.module('myModule') 
    .controller('myCtrl', ['userDetails', function(userDetails) { 
     console.log(userDetails); 
     }]; 

Dadurch werden die Benutzerdaten laden, während die Seite geladen wird.

0

Ich löste dieses Problem, indem ich das defer-Objekt als globales Objekt verwende, so dass es nur einmal initialisiert wird.

Verwandte Themen