【问题标题】:AngularJS - Running a function once on loadAngularJS - 在加载时运行一次函数
【发布时间】:2015-08-23 02:39:14
【问题描述】:

我正在尝试在我的 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 调用完成之前加载。

【问题讨论】:

  • 这个请求会加载什么数据?
  • 这会加载一个用于所有后续请求的 ID 号。 ID 保存在服务中。
  • 记得把答案标记为已接受,这样其他新人就不会纠结了

标签: angularjs


【解决方案1】:

问题

Angular 不是动态的,您不能动态添加控制器,也不能工厂等。您也不能推迟控制器引导,Angular 将所有内容加载在一起,这是相当不利的(将在 Angular 2 中修复)

治疗

但是 javascript 本身有一个非常重要的特性——closure,它可以随时随地工作。
并且 Angular 有一些内部服务可以注入到 Angular 生态系统之外,甚至可以注入到浏览器控制台中。这些服务注入如下所示。 从技术上讲,我们可以使用其他任何东西(jQuery.ajaxwindow.fetch,甚至是XMLHttpRequest),但让我们坚持使用全角度解决方案

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

行为

首先,我们推迟整个 Angular 应用程序引导,注入 http 服务。然后你提出你需要的请求,接收数据,然后关闭开始工作,我们将接收到的数据传递给一些服务,或者我们也可以分配给一些 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

【讨论】:

    【解决方案2】:

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

    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

    这是我使用服务发现的一个 plunkr,这是我推荐的。 http://plnkr.co/edit/XKGC1h?p=info

    【讨论】:

    • 这必须是最顶层的状态
    • 我不这么认为他想加载数据..他想在运行阶段加载配置设置
    • 我想知道这是否是解决我的问题的最佳方法。虽然这个解决方案可行,但我想避免为每个控制器编写这个。我只需要加载一次数据,我将把它保存到服务中(我需要把它放在我原来的问题中......)
    • 现在我明白了。您有一个控制器高于其他控制器。这是有道理的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-04
    • 1970-01-01
    • 1970-01-01
    • 2017-10-21
    • 2012-08-13
    • 1970-01-01
    相关资源
    最近更新 更多