AngularJS - 在加载

时间:2015-08-22 16:08:23

标签: angularjs

我正在尝试在首次加载AngularJS应用程序时运行$ http函数。

这个$ http函数需要在我的应用程序中的任何控制器正常运行之前完成。我该怎么做呢?这听起来像是一个承诺,但听起来我会在每个控制器中创造一个承诺......

我目前首先要运行的功能如下:

app.run(function() {

    $http.get('link').success(function(data) {

      // success function. The data that I get from this HTTP call will be saved to a service.

    }).error(function(error) {

    });

});

但是,有时控制器将在http调用完成之前加载。

2 个答案:

答案 0 :(得分:2)

问题

Angular不是动态的,你不能动态添加控制器,也不能动态添加工厂等。另外你不能推迟控制器引导,角度加载所有东西,这是非常不利的(将在Angular 2中修复)

治愈

但是javascript本身具有非常重要的功能 - closure,可随时随地使用 而角度有一些内部服务,可以注入角度生态系统之外,甚至可以注入浏览器控制台。注入的服务如下所示。 我们在技术上可以使用其他任何内容(jQuery.ajaxwindow.fetch,甚至使用XMLHttpRequest),但让我们坚持使用全角度解决方案

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

行为

首先,我们推迟整个角度应用程序引导,注入http服务。然后你提出你需要的请求,接收数据,然后关闭get工作,我们将接收到的数据传递给某些服务,或者我们也可以分配一些angular.constant或angular.value但是让我们用angular.service进行演示,所以当您的服务有数据时,引导整个应用程序,以便所有控制器都使用您所需的数据进行初始化 基本上这样的任务就像这样解决了

<body>
  <div ng-controller="Controller1">
    <b>Controller1</b>
    {{text}}
    {{setting.data.name}}
  </div>
  <hr>
  <div ng-controller="Controller2">
   <b>Controller2</b>
    {{text}}
    {{setting.data.name}}
  </div>
  <script>
    //define preloader
    var $http_injected = angular.injector(["ng"]).get("$http");
    $http_injected.get('http://jsonplaceholder.typicode.com/users/1').then(function(successResponse) {

      //define app
      angular.module('app', []); 

      //define test controllers
      //note, usually we see 'controller1 loaded' text before 'settings applied', because controller initialized with this data, but in this demo, we will not see 'controller1 loaded' text, as we use closure to assign data, so it's instantly changed
      angular.module('app').controller('Controller1', function($scope, AppSetting) {
        $scope.text = 'controller1 loaded';
        $scope.setting = AppSetting.setting;
        $scope.$watch('setting', function(e1 ,e2){
          $scope.text = 'settings applied'
        });
      });
      angular.module('app').controller('Controller2', function($scope, AppSetting) {
        $scope.text = 'controller2 loaded';
        $scope.setting = AppSetting.setting;
        $scope.$watch('setting', function(e1 ,e2){
          $scope.text = 'settings applied'
        });
      });

      //define test services, note we assign it here, it's possible
      //because of javascript awesomeness (closure)
      angular.module('app').service('AppSetting', function() {
        this.setting = successResponse;
      });

      //bootstrap app, we cannot use ng-app, as it loads app instantly
      //but we bootstrap it manually when you settings come
      angular.bootstrap(document.body, ['app']);
    });
  </script>
</body>

Plunker demo

答案 1 :(得分:0)

您可以在配置路线时执行此操作

app.config(['$routeProvider', function ($routeProvider) {
  $routeProvider
    .when('/', {
      controller: 'MainCtrl',
      templateUrl: 'main.html',
      resolve: {
        data: ['$http',
          function($http)
          {
            return $http.get('/api/data').then(
                function success(response) { return response.data.rows[0]; },
                function error(reason)     { return false; }
              );
          }
        ]
      }
    });
}]);

类似的问题: AngularJS - routeProvider resolve calling a service method

AngularJS: $routeProvider when resolve $http returns response obj instead of my obj

下面是我发现使用服务的傻瓜,这是我推荐的。 http://plnkr.co/edit/XKGC1h?p=info