2014-11-07 11 views
11

Jak mogę zainicjować moją aplikację angularjs na bieżąco z odpowiedzią żądania GET.

Na przykład: -

angular.module('A',[]); 
    angular.module('A').run(function ($rootScope,$http){ 
     $rootScope.safeApply = function (fn) { 

       $http.get('url').success(function(result){ 

        // This doesn't work. I am not able to inject 'theConstant' elsewhere in my application 
        angular.module('A').constant('theConstant', result); 
       });     
       var phase = $rootScope.$$phase; 
       if (phase === '$apply' || phase === '$digest') { 
        if (fn && (typeof (fn) === 'function')) { 
         fn(); 
        } 
       } else { 
        this.$apply(fn); 
       } 
      }; 
     }); 

Chcę ustawić stały się natomiast moja aplikacja zainicjowana i móc dzielić stała naprzeciwko moich komponentów.

Jakie jest najlepsze podejście, aby to osiągnąć?

+0

co jest 'theValueFromHttpCall'? – akonsu

+0

@akonsu Zaktualizowano pytanie. W moim przypadku odpowiedź byłaby obiektem JSON. –

+0

interesujące. Domyślam się, że wtryskiwacz ma już wszystkie komponenty zdefiniowane przy starcie, więc myślę, że konieczne jest, aby pracować z nim bezpośrednio, aby włączyć twój scenariusz. – akonsu

Odpowiedz

5

Wynik $http.get jest niedostępny podczas inicjalizacji aplikacji. Jest dostępny tylko wtedy, gdy serwer go dostarczy. Z tego powodu po prostu utrzymanie tej wartości w stałej modułu jest niemożliwe. Ryzykujesz jednak, że możesz

Możesz jednak zawinąć połączenie do usługi $http.get i wprowadzić tę usługę, gdziekolwiek chcesz. (Należy pamiętać, że usługi nie mogą być wstrzykiwane w blokach konfiguracyjnych.)

// grab the "constant" 
angular.module('A').factory('almostConstant', function() { 
    return $http.get('url').then(function(response) { 
    return response.data; 
    }); 
}); 

// use the "constant" 
angular.module('A').controller('controller', function($scope, almostConstant) { 
    almostConstant.then(function(data){ 
    $scope.almostConstant = data; 
    }); 
}); 

Tryb nieco niewygodne, aby uzyskać dostęp wartość swojej almostConstant to ze względu na jego charakter asynchroniczny. Po prostu jest dostępny w nieokreślonym czasie, więc próba dostępu do niego w sposób synchroniczny może wprowadzić wiele subtelnych błędów czasowych.


Bardzo nieokreślonym sposobem jest wpisanie stałej w pliku JS bezpośrednio. W tej chwili Twój serwer może odpowiedzieć na żądanie o wartości 'url'. Zamiast tego, można zrobić to odpowiedzieć na wezwanie do 'url.js' z następujący ciąg:

angular.module('A').constant('theConstant', result); 

gdzie wynik jest oczywiście swoją stałą. Na przykład, jeśli były przy użyciu PHP na backend mogłoby to wyglądać mniej więcej tak:

<?php 
    header('Content-Type: application/javascript'); 
    $constant = retrieveMyConstant(); 
?> 
angular.module('A').constant('theConstant', <?php echo $constant; ?>); 

Upewnij się, że stała faktycznie wygląda wartości JavaScript. Jeśli jest to ciąg, zawinąć go w ', czy jest to obiekt JSON napisać swoje serializacji itp

Po tym po prostu zawierać tag skryptu wskazując url.js w pliku index.html.

Zauważ, że to rozwiązanie jest synchroniczny, więc jeśli pobieranie stała na serwerze zajmuje trochę czasu, będzie to mieć wpływ na czas ładowania strony.

+0

W moim przypadku nie ma stron internetowych po stronie serwera. Myślę więc, że będę musiał pójść z pierwszym podejściem, które zaproponowałeś. –

+0

Dzwonisz na serwer za każdym razem, gdy chcesz odczytać stałą wartość, a nie dobre rozwiązanie. – Abhijeet

+0

@Abhijeet Metoda fabryczna jest nazywana pojedynczym czasem, więc pojedyncze wywołanie '$ http.get' jest wykonywane na stronie, więc jedno żądanie jest wysyłane na serwer. Zapraszam do wypróbowania w prostym przykładzie. – Tibos

1

zorientowali się, że przy użyciu właściwości „rozpoznawać” albo w standardowym routerem kątowej lub podczas korzystania z UI-Router jest lepszy sposób, aby zainicjować swoją aplikację.

To skąd podczas korzystania UI-Router: -

  1. Zdefiniuj najwyższego poziomu stanu abstrakcyjne z pustym inline szablonie tak: -
$stateProvider.state('root',{ 
    abstract:true, 
    template:'<ui-view/>', 
    resolve : { 
     securityContext : function($http){ 
      return $http.get("/security/context"); 
     } 
    } 
}); 
}); 

Nieruchomość do rozwiązania są wymagane przez aplikację. Podobnie jak - token bezpieczeństwa, aktualnie zalogowany użytkownik itp.

  1. Definiowanie stanu dziecka dziedziczącego z powyższego stanu. Każda część aplikacji musi być zarządzana przez państwo.
$stateProvider.state('root.optosoft.home',{ 
    url:'/home', 
    templateUrl : '/assets/home-module/partial/home/home.html', 
    controller: 'HomeCtrl', 
    resolve : { 
     accounts : function(securityContext){ 
      // Child state wil first wait for securityContext to get resolved first 
     } 
    } 
}); 
5

Jak wyjaśniono w this blog post można init, stała przed ładowanie początkowe swoją aplikację:

(function() { 
    var app = angular.module("A", []); 

    var initInjector = angular.injector(["ng"]); 
    var $http = initInjector.get("$http"); 

    return $http.get("/path/to/data.json") 
     .then(function(response) { 
      app.constant("myData", response.data); 
     }) 
     .then(function bootstrapApplication() { 
      angular.element(document).ready(function() { 
       angular.bootstrap(document, ["A"]); 
      }); 
     }); 


}()); 
Powiązane problemy