1

我想在我的控制器内的 $scope 中加载 2 个 json 数据,然后再执行类似基本案例的操作。但是我工厂中的 $http 返回状态对象,因为它返回了一个承诺。

我的提供者作为工厂对象

(function(angular) {
   'use strict';
    angular.module('myModule').factory("config", function($http) {
        return{
            getConfig: function () {
                return $http.get('json/config.json').then(function(response) {
                    return response.data;
               });
            },
            getPreferences:  function () {
                return $http.get('json/preferences.json').then(function(response) {
                     return response.data;
                });
           }
      }; 
   }); 
})(window.angular);

如何将我的所有外部 json 数据存储在我的主控制器内的 $scope 变量中的多个文件中而不会超时或添加几个嵌套的 promise.then ?实际上,我想知道是否有办法在控制器加载之前存储所有 json 数据?

(function(angular) {
    'use strict';
    angular.module('myModule')
    .controller('MainCtrl', ['$scope', 'config', function ($scope, config, ){
        $scope.config = ?????????? ;
        $scope.preferences = ???????????? ;             
     }]);
})(window.angular);
4

3 回答 3

3

只需从您的控制器中的服务调用您的方法config...

(function(angular) {
    'use strict';
    angular.module('myModule')
    .controller('MainCtrl', ['$scope', 'config', '$q', function ($scope, config, $q) { 
       config.getConfig().then(function(data) {
         $scope.config = data;
       });
       config.getPreferences().then(function(data) {
         $scope.preferences = data;
       });

       // or if you want, 
       // you can wait for the both requests to finish and get them at once
       $q.all([
            config.getConfig(),
            config.getPreferences()
       ])
       .then(function(responses) {
          $scope.config = responses[0];
          $scope.preferences = responses[1];
       });
     }]);
})(window.angular);

如果您在控制器初始化之前需要此配置数据并且您正在使用路由器,您可以从路由器解决它,当您的控制器被触发时它将可用。

路由器

  $stateProvider
    .state('stateName', {
      url: '/stateURL',
      templateUrl: 'path/to/the/template',
      controller: 'MainCtrl',
      resolve: {
        configData: ['$q', config, function ($q, config) {
          return $q.all([
            config.getConfig(),
            config.getPreferences()
          ]);
       }
     }
   });

控制器

(function(angular) {
  'use strict';
  angular.module('myModule')
    .controller('MainCtrl', ['$scope', 'configData', function ($scope, configData) {
      $scope.config = configData[0];
      $scope.preferences = configData[1];
  }]);

已编辑

于 2017-07-19T14:32:50.563 回答
2

只需调用您的 getConfig 函数并使用返回的承诺:

config.getConfig()
    .then(function(data) {
        // In your config factory you choose to return reponse.data so in this callback data = response.data
        $scope.config = data
     }

config.getPreferences()
    .then(function(data) {
        // In your config factory you choose to return reponse.data so in this callback data = response.data
        $scope.preferences = data
     }

在您的工厂中,您返回一个 Promise 并将其配置为使用 response.data 解析,因此当您解析返回的 Promise 时,该字段将直接返回。

于 2017-07-19T14:34:33.133 回答
1

我的问题是当我必须获取两个 json 数据时,我应该在 promise.then 中执行 promise.then。我想在控制器中执行我的代码之前找到一个加载所有 json 数据的解决方案

使用$q.all等待几个 promise 完成:

var configPromise = config.getConfig();
var prefPromise = config.getPreferences();

$q.all([configPromise, prefPromise]).then(function(dataList) {
    $scope.config = dataList[0];
    $scope.preferences = dataList[1];

    console.log($scope.config);
    console.log($scope.preferences);

    //Put more code here
});
        

有关更多信息,请参阅AngularJS $q 服务 API 参考 - $q.all


如果你console.log($scope.config)在函数之外做getConfig,那就错了,因为它是undefined.

这就是异步 API 的工作方式。成功处理程序中的代码在.then方法外部的所有代码之后执行。

将 console.log放在处理函数中:

config.getConfig().then(function successHandler(data) {
    $scope.config = data
    //HERE
    console.log($scope.config);
};

//NOT HERE
 ̶c̶o̶n̶s̶o̶l̶e̶.̶l̶o̶g̶(̶$̶s̶c̶o̶p̶e̶.̶c̶o̶n̶f̶i̶g̶)̶;̶

基于 Promise 的异步操作的解释

console.log("Part1");
console.log("Part2");
var promise = $http.get(url);
promise.then(function successHandler(response){
    console.log("Part3");
});
console.log("Part4");

图片

“第 4 部分”的控制台日志不必等待数据从服务器返回。它在 XHR启动后立即执行。“第 3 部分”的控制台日志位于成功处理函数中,该函数由$q 服务持有,并在数据从服务器到达并且 XHR完成调用。

有关更多信息,请参阅如何在成功处理程序之外使用 $http 承诺响应。


演示

console.log("Part 1");
console.log("Part 2");
var promise = new Promise(r=>r());
promise.then(function() {
    console.log("Part 3");
});
console.log("Part *4*");

于 2017-07-19T16:04:23.293 回答