2017-03-02 3 views
0

Ich habe eine AngularJS-Anwendung, wo ich einige grundlegende Informationen, die ich vom Server über Async-Aufruf erhalten, bevor ich weiter laden oder die Seite verarbeiten kann.AngularJS laden Daten vor der Anwendung

Ich weiß, es gibt andere ähnliche Fragen dazu, aber alle anderen, die ich gefunden habe, beziehen sich auf das Laden eines Daten vor der Initialisierung eines bestimmten Teils (Richtlinie, Controller, Fabrik, etc ..).

Was ich will ist, diese Daten an mehreren Orten zu verwenden, spielt keine Rolle, ob es eine Komponente, Richtlinie usw. ist. Wenn ich in einem von ihnen ohne die Daten initialisiere, kann ich nicht fortfahren .

Zum Beispiel: Ich habe ein div in meinem footer, wo ich einen Standort mit Google Maps anzeigen, also brauche ich den Ort, bevor ich den Code zum Platzieren der Google Maps ausführen kann (derzeit in einer Richtlinie). Ich machte einen Plünderer, um dieses Problem zu veranschaulichen (ohne die unten erwähnte Lösung).

https://plnkr.co/edit/2RkansVp3NQNx3Tb4lMD?p=preview


Was habe ich

ich dieses Problem durch die Verwendung ui-Router resolve lösen könnte, obwohl es der richtige Weg zu sein scheint nicht, dies zu tun. Ich benutze einen "leeren" Zustand, nur um die Daten aufzulösen und die Grundelemente von der index.html auf diese app.html Seite zu verschieben, was mein Index wäre, aber da ich die Daten laden muss, musste ich umziehen .

Dies ist mein Code:

.state('app', { 
    abstract: true, 
    views: { 
     'main': { 
      templateUrl: 'view/app.html' 
     } 
    }, 
    resolve: { 
     dataLoad: function($q, api, store) { 
      var promises = { 
       //[..loading more data..] 
       location: api.request('getLocation') 
      } 

      return $q.all(promises).then(function(resolve){ 
       //[..resolving more data..] 
       return store.location = resolve.location; 
      }) 
     } 
    } 
}) 
.state('home', { 
    parent: 'app', 
    url: '/Home', 
    views: { 
     'app': { 
      templateUrl: 'view/home.html' 
     } 
    } 
}) 

index.html

<body ui-view="main"></body> 

app.html

<header>[...]</header> 

<main ui-view="app"></main> 

<footer>[...]</footer> 

So kann ich richtig alle Daten initiieren kann, seit der app.html wi ll laden nur nach der Auflösung im übergeordneten App-Status.

Aber wie Sie sehen können, ist meine index.html vollständig leer und ich musste die app.html erstellen, nur um diese Situation zu umgehen.


Ist dies der Weg zu gehen? Oder gibt es eine bessere/korrekte Methode, um die Daten zu laden, bevor ich meine Anwendung einleite, oder um in einen anderen Bereich zu laden (.run, zum Beispiel) und zu warten, bis alle Daten aufgelöst sind?

+0

Diese Daten, die Sie laden müssen, werden nur einmal geladen ... oder müssen mehrmals abgerufen werden (z. B. wenn sie sich im Laufe der Zeit ändern und Sie sie dann erneut abrufen müssen)? – lealceldeiro

+0

@lealceldeiro nur einmal. Die Daten können sich ändern, aber nur wenn sich der Benutzer selbst ändert, was nicht häufig geschieht. – celsomtrindade

+0

Laut [der Dokumentation für Lösung] (https://github.com/angular-ui/ui-router/wiki#resolve) wird Ihr Status erst dann angenommen, wenn die vom Auflösungsaufruf zurückgegebenen Versprechen gelöst sind. Ich bemerke, dass Ihre Kommentare anzeigen, dass Sie "mehr Daten laden" innerhalb der Auflösung Ihres "$ q.all" -Aufrufs, aber keine Versprechen davon zurückgeben. Wenn dies der Fall ist, müssen Sie nur ein weiteres Versprechen aus diesem Aufruf zurückgeben, sobald Sie alle Daten haben. Sie könnten auch in verschachtelte Zustände schauen und die "resolve" in einen "root" -Zustand setzen, dann die Zustände, die die darunter liegenden Daten verwenden, wie "root.home" ... –

Antwort

0

EDITED: für Asynchron-Anruf warten und dann Bootstrap App

(function() { 
    var initInj = angular.injector(['ng']); 
    var $http = initInj.get('$http'); 
    $http.get('<your_req_url>').then(
    function (res) { 
     //set your data camming from server in 'res' 
     //bootstrap app! 
     angular.element(document).ready(function() { 
      angular.bootstrap(document, ['myApp']); 
     }); 
    } 
); 
})(); 

========================== =============

Original-Beitrag

sollten Sie verwenden die Lauf func des AngularJS module.Hier auf SO gibt es eine related question, in der dieses Thema ausführlich erklärt wird.

Aber im Grunde würden Sie dies tun:

angular.module('app',[]) 
    .run([function(){ 
      //..load all your required data here 
    }]); 

Nachdem die Daten Aufladungstyp, können Sie es in einem Betrieb genommen, so dass, wenn der Benutzer diese Daten ändern Sie es in den Dienst für die künftige Nutzung aktualisieren.

+0

Ich weiß, dass der .run-Block vor dem Controller und allem anderen ausgeführt wird. Es verhindert jedoch nicht, dass es fortgesetzt wird, wenn die Daten noch verarbeitet werden. Das ist das Problem. Zu dem Zeitpunkt, zu dem die Richtlinie aktiviert wird, muss ich die Daten bereits haben. – celsomtrindade

+0

Wenn Sie sagen, wenn die Daten noch verarbeitet werden. ... über welche Art von Verarbeitung sprechen wir? eine Art von async Operation (oder ähnlich), die die Daten ändern wird, nachdem dieser Block ausgeführt wurde? – lealceldeiro

+0

Ich bekomme diese Daten vom Server, über $ http Service. – celsomtrindade

Verwandte Themen