我希望在执行类似基本案例的操作之前在我的控制器中的$ 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);
答案 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");
“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*");