在Angular 1.6中,如何在控制器内的$ scope中使用几个json正确配置数据?

时间:2017-07-19 14:27:03

标签: angularjs angular-promise angular-factory

我希望在执行类似基本案例的操作之前在我的控制器中的$ scope中加载2个json数据。但是我工厂里面的$ http返回状态对象,因为它返回了一个promise。

我的提供者作为工厂对象

.Elements("html")

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

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

3 个答案:

答案 0 :(得分: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];
  }]);

被修改

答案 1 :(得分:2)

只需调用getConfig函数并使用返回的promise:

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
     }

在您的工厂中,您返回一个承诺并将其配置为使用response.data解析,以便在您解析返回的承诺时直接返回此字段。

答案 2 :(得分:1)

  

我的问题是,当我必须得到两个json数据时,我应该在promise.then内做promise.then。我想在控制器

中执行我的代码之前找到加载所有json数据的解决方案

使用$q.all等待多个承诺完成:

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 Service API Reference - $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̶)̶;̶

基于承诺的异步操作的解释

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

pic

“Part4”的控制台日志不必等待数据从服务器返回。它在XHR 启动后立即执行。 “Part3”的控制台日志位于成功处理函数内部,该函数由$q service保留,并在数据从服务器到达并且XHR 完成后调用

有关详细信息,请参阅How to use $http promise response outside success handler.

演示

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*");