2015-06-11 6 views
5

pracuję w aplikacji mobilnej za pomocą angularjs jako ramy, obecnie mam strukturę podobną do tej:angularjs App: ładowanie danych z JSON raz i użyć go w kilku kontrolerów

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) { 

}]); 

a potem „m wyświetlanie zawartości z ng-view:

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

wszystko działa dobrze, ale muszę się wczytać dane z pliku JSON, aby wypełnić całą zawartość aplikacji. Chcę tylko i tylko zadzwonić do AJAX tylko raz, a następnie przekazać dane przez wszystkie moje różne kontrolery. W mojej pierwszej próbie, myślałem, aby stworzyć usługę z $http.get() w środku i to, że w każdym kontrolerze, ale to nie działa, ponieważ robi różne żądanie ajax za każdym razem wstrzyknąć i korzystać z usługi. Ponieważ jestem nowy przy użyciu kątowego, zastanawiam się, jaki jest najlepszy lub bardziej "kątowy" sposób, aby to osiągnąć, nie psując tego.

Edit: Dodaję kod usługi, która jest tylko prosty $http.get prośba:

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

Usługa brakuje przykład kod, który byłby najbardziej przydatny do zobaczenia tutaj. – seanhodges

+0

@Didier Proponuję podzielić pliki kodu na różne kontrolery i użyć usługi do pobierania danych. zobacz moją odpowiedź na kod usługi –

Odpowiedz

4

Spróbuj dostać JSON danych z Pobierz 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'))); 

Teraz można dodać tę zależność w pliku sterownika i zastosowanie:

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

To działało jak zaklęcie, chciałbym rozwiązać ten problem na kilka sposobów, ale nigdy nie przyszło mi do głowy użycie wzoru singleton. Dzięki! – Didier

+0

Otrzymuję 'this is undefined' dla wiersza' this.data = data; ', a jeśli go usunę, to żądanie GET dzieje się wiele razy. Dowolny pomysł? – bjesus

+0

Inicjowanie nowej obietnicy nie jest konieczne, ponieważ $ http zwraca obietnicę, zamiast tego można zwrócić odwołanie do obietnicy, odpowiedź jest poprawna, ale może być bardziej zwięzła –

7

Inicjalizować obietnicę raz, i zwraca referencję do niego:

nr trzeba zainicjować kolejną obietnicę. $ http zwraca jeden.

Wystarczy przykleić do .then() połączenia na swojej obietnicy zmodyfikować wynik

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

Edycja: można rozważyć użycie $ cache zamiast http. Może osiągnąć takie same wyniki. From the docs:

Jeśli wiele identycznych żądania są wykonane przy użyciu tej samej pamięci podręcznej, która nie jest jeszcze wypełniony, jeden wniosek zostanie wykonany z serwerem i pozostałe wnioski powróci taką samą odpowiedź.

+0

Działa to dobrze, jeśli nie musisz modyfikować/traktować danych zwróconych przez odpowiedź get, ponieważ ten powrót obietnicy zamiast danych, niestety nie było to moim przypadkiem. Dzięki za odpowiedź. – Didier

+0

przykład można przedłużyć, aby to zrobić :) –

+0

Tak Można go przedłużyć, w rzeczy samej jest to bardzo dobra odpowiedź, jedynym powodem, dla którego nie wybrałem go jako "zaakceptowaną odpowiedź" było to, że już odpowiedź haw-i-a uznał fakt, że dane mogą być traktowane. Wielkie dzięki, znowu. – Didier

Powiązane problemy