2015-06-11 14 views
5

sto lavorando su un app mobile utilizzando AngularJS come un quadro, attualmente ho una struttura simile a questo:AngularJS App: Caricare i dati da JSON una volta e utilizzarlo in diversi controller

app.config(['$routeProvider', function($routeProvider) { 
    $routeProvider 
     .when('/', { 
      templateUrl : 'pages/home.html', 
      controller : 'homeCtrl' 
     }) 

     .when('/one', { 
      templateUrl : 'pages/one.html', 
      controller : 'oneCtrl' 
     }) 

     .when('/two', { 
      templateUrl : 'pages/two.html', 
      controller : 'twoCtrl' 
     }); 
}]); 

app.controller('homeCtrl', ['$scope', function($scope) { 

}]); 

app.controller('oneCtrl', ['$scope', function($scope) { 

}]); 

app.controller('twoCtrl', ['$scope', function($scope) { 

}]); 

E poi ho 'm che visualizza il contenuto con una ng-view:

<div class="ng-view></div> 

le cose stanno funzionando bene, ma ho bisogno di caricare i dati da un file JSON per popolare tutti i contenuti dell'app. Quello che voglio è fare e una chiamata AJAX solo una volta e quindi passare i dati attraverso tutti i miei controller diversi. Nel mio primo tentativo, ho pensato di creare un servizio con uno $http.get() all'interno di esso e includerlo in ogni controller, ma non funziona perché fa una richiesta ajax diversa ogni volta che iniettare e utilizzare il servizio. Dal momento che sono nuovo con l'angolare, mi chiedo quale sia il modo migliore o il più "angolare" per ottenere ciò senza complicarlo.

Edit: sto aggiungendo il codice del servizio, che è solo un semplice $http.get richiesta:

app.service('Data', ['$http', function($http) { 
    this.get = function() { 
     $http.get('data.json') 
     .success(function(result) { 
      return result; 
     }) 
    } 
}); 
+2

Il servizio non è presente l'esempio codice, che sarebbe la cosa più utile da vedere qui. – seanhodges

+0

@Didier Ti suggerisco di dividere i file di codice in controller diversi e utilizzare un servizio per questo recupero dati. vedere la mia risposta per il codice di servizio –

risposta

4

Prova questo per ottenere JSON dati da un GET Link:

(function (app) { 
    'use strict'; 

    app.factory('myService', MyService); 

    MyService.$inject = ['$q', '$http']; 

    function MyService($q, $http) { 
     var data; 

     var service = { 
      getData: getData 
     }; 

     return service; 

     ////////////////////////////////////// 

     function getData(refresh) { 
      if (refresh || !data) { 
       return $http.get('your_source').then(function(data){ 
        this.data = data; 
        return data; 
       }) 
      } 
      else { 
       var deferrer = $q.defer(); 
       deferrer.resolve(data); 
       return deferrer.promise; 
      } 
     } 
    } 

}(angular.module('app'))); 

Ora è possibile aggiungere questa dipendenza nel file di controllo ed impiego:

myService.getData().then(function(data){ 
    //use data here 
}, function(err){ 
    //Handle error here 
}); 
+0

Questo ha funzionato come un fascino, ho pensato di risolvere questo problema in molti modi, ma non mi è mai venuto in mente un motivo singleton. Grazie! – Didier

+0

Ricevo 'questo è undefined' per la riga' this.data = data; ', e se lo rimuovo la richiesta GET si verifica più volte. Qualche idea? – bjesus

+0

inizializzare una nuova promessa non è necessaria in quanto $ http restituisce una promessa, puoi invece restituire un riferimento alla promessa, la risposta è corretta ma può essere più concisa –

7

inizializzare la promessa, una volta, e restituire un riferimento ad esso:

No bisogno di inizializzare un'altra promessa. $ http restituisce uno.

Basta virare una chiamata .then() sulla vostra promessa di modificare il risultato

angular.module('app', []) 
    .service('service', function($http){ 
    this.promise = null; 
    function makeRequest() { 
     return $http.get('http://jsonplaceholder.typicode.com/posts/1') 
      .then(function(resp){ 
        return resp.data; 
      }); 
    } 
    this.getPromise = function(update){ 
     if (update || !this.promise) { 
     this.promise = makeRequest(); 
     } 
     return this.promise;  
    } 
    }) 

Codepen example

Edit: potete prendere in considerazione $ http cache invece. Può raggiungere gli stessi risultati. From the docs:

Se più richieste identiche sono realizzati con la stessa cache, che non è ancora popolata, sarà effettuata una richiesta al server e le richieste rimanenti restituirà la stessa risposta.

+0

Questo funziona bene se non è necessario modificare/trattare i dati restituiti dalla risposta di ottenere dal momento che questo restituisce la promessa stessa invece dei dati, sfortunatamente non era il mio caso. Grazie per la risposta. – Didier

+0

l'esempio può essere esteso per farlo :) –

+0

Sì Può essere esteso, anzi questa è un'ottima risposta l'unica ragione per cui non l'ho scelta come "risposta accettata" era perché la risposta di haw-i-già considerato il fatto che i dati potrebbero essere trattati. Grazie mille, ancora. – Didier