2014-11-07 3 views
11

Как я могу инициализировать my appular contularjs с ответом на запрос GET.

Например: -

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); 
       } 
      }; 
     }); 

Я хочу, чтобы установить константу в то время как мое приложение инициализируются и быть в состоянии разделить константу через мои компоненты.

Каков наилучший подход для этого?

+0

что 'theValueFromHttpCall'? – akonsu

+0

@akonsu Обновлен вопрос. В моем случае ответом будет объект JSON. –

+0

интересный. Я бы предположил, что у инжектора уже есть все компоненты, определенные при загрузке, поэтому я думаю, что нужно работать с ним напрямую, чтобы включить ваш сценарий. – akonsu

ответ

5

Результат $http.get не доступен, когда приложение инициализировано. Он доступен только тогда, когда сервер доставляет его. По этой причине простое сохранение этого значения в постоянном модуле невозможно. Вы рискуете

Что вы можете сделать, однако, оберните вызов $http.get в службу и приложите эту услугу, где бы вы ни находились. (Обратите внимание, что услуги не могут быть введены в конфигурации блоков.)

// 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; 
    }); 
}); 

слегка неудобный режим для доступа к значению вашего almostConstant связано с его асинхронной природы. Он просто доступен в неуказанное время, поэтому попытка получить доступ к нему синхронно может привести к множеству тонких ошибок времени.


Очень не угловатым способом сделать это было бы написать вашу константу в JS-файле напрямую. На данный момент ваш сервер может ответить на запрос 'url' со значением. Вместо этого, вы можете сделать это ответить на запрос 'url.js' со следующей строкой:

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

, где результат, очевидно, ваша постоянная. Например, если вы используете PHP на серверном это может выглядеть примерно так:

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

Убедитесь, что константа на самом деле выглядит как значение JavaScript. Если это строка, завернуть его в ', если это объект JSON написать свою сериализацию и т.д.

После этого вы просто включить скрипт тег, указывающий на url.js в файле index.html.

Обратите внимание, что это решение синхронно, поэтому, если получение константы на сервере занимает некоторое время, это повлияет на время загрузки страницы.

+0

В моем случае нет веб-страниц на стороне сервера. Поэтому я думаю, что мне придется пойти с первым подходом, который вы предложили. –

+0

Вы вызываете сервер каждый раз, когда хотите читать постоянное значение, а не хорошее решение. – Abhijeet

+0

@Abhijeet. Заводский метод называется единовременным, поэтому на странице делается один вызов '$ http.get', поэтому на сервер отправляется один запрос. Не стесняйтесь попробовать в простом примере. – Tibos

1

Я понял, что использование свойств «разрешения» в стандартном угловом маршрутизаторе или при использовании UI-Router - лучший способ инициализировать ваше приложение.

Это как же при использовании UI-маршрутизатор: -

  1. Определение абстрактного состояния верхнего уровня с пустым шаблоном инлайн, как это: -
$stateProvider.state('root',{ 
    abstract:true, 
    template:'<ui-view/>', 
    resolve : { 
     securityContext : function($http){ 
      return $http.get("/security/context"); 
     } 
    } 
}); 
}); 

Свойство которые должны быть решены, - это то, что требуется через ваше приложение. Как - токен безопасности, в настоящее время зарегистрированный пользователь и т. Д.

  1. Определить дочернее состояние, наследующее состояние выше. Каждая часть вашего приложения должна управляться государством.
$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

Как объяснено в this blog post, вы можете инициализировать константу, прежде чем развернув приложение:

(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"]); 
      }); 
     }); 


}()); 
Смежные вопросы