我一直在尝试用角度制作一个漂亮且用户友好的应用程序,我正在让用户知道在我发出ajax请求时正在加载的部分。我想要完成的任务:我想创建一个处理初始化数据获取的服务,并在数据可用时将数据作为对象传递给控制器。当然,在我的控制器需要的所有初始数据可用之前,视图不会显示。这是我到目前为止所拥有的:
app.js
var Application = angular.module('ReporterApplication', ['ngRoute']);
Application.service('Initialize', ['$http', '$q', '$timeout', function($http, $q, $timeout)
{
this.serverData = function()
{
$http.get('/packing/scan.action')
.success(function(data)
{
return data;
})
.error(function(data)
{
return data;
});
};
}])
Application.config(['$routeProvider', '$interpolateProvider',
function($routeProvider, $interpolateProvider) {
$interpolateProvider.startSymbol('<%');
$interpolateProvider.endSymbol('%>');
$routeProvider
.when('/packing/scan.html', {
templateUrl: 'packing/scan.html',
controller: 'PackingScanController as packer',
resolve: {
initData : 'Initialize' .... etc more code
scan.js
Application.controller('PackingScanController', ['$scope', '$http', 'initData', function($scope, $http, initData) {
var packer = this;
packer.packedToday = initData.serverData(); ... etc more code
答案 0 :(得分:1)
如果您希望控制器等待,您需要做的是正确配置resolve
选项。为此,您需要让您的服务返回一个承诺,否则路由器将不会等待。
resolve - {Object.<string, function>=}
- 应该注入控制器的可选依赖关系图。 如果这些依赖项中的任何一个是承诺,路由器将等待它们全部被解析或者在实例化控制器之前被拒绝。
这是一个简单的例子:
app.service('Initialize', ['$http', function($http) {
this.serverData = function()
{
// return the http promise
return $http
.get('config.json')
// use success/error if needed
.then(function (response) {
// make sure, only the response data is used
return response.data;
})
;
};
}]);
app.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/', {
template: '<pre>{{ main.initData|json }}</pre>',
controller: 'MainCtrl as main',
resolve: {
// configure with DI
initData: ['Initialize', function (Initialize) {
// call the service method, and return the promise
return Initialize.serverData();
}]
}
})
;
}]);
app.controller('MainCtrl', function (initData) {
// initData will be loaded
this.initData = initData;
});
答案 1 :(得分:0)
您可以在任何控制器中注入您的服务,这样您就不需要通过解决方案传递它。
Application.controller('PackingScanController', ['$scope', '$http', 'Initialize', function($scope, $http, Initialize)
对于装载机,通常我所做的是使用ng-show
检查模板中数据的可用性<div ng-show="!data">Loading...</div>
<div ng-show="!!data" ng-repeat="d in data">...</div>
每当您需要显示加载程序时,只需将您的$ scope.data设置为null并继续调用您的API服务。
顺便提一下,如果您的评论中没有其他用户建议,您的服务将无法正常运行。
答案 2 :(得分:0)
所有这些错误都来自于我们正在尝试将异步调用转换为同步调用。这根本不可能。
serverData()不再返回任何内容。返回数据 语句未从serverData()返回。它从...返回 匿名回调函数传递给then()。
不会立即调用匿名回调。它叫做什么时候 响应是可用的。这种情况发生在serverData()之后很久 返回。
所以, 的 1。单向:使用回调
Application.service('initdata',function($http){
var serverData = function(callback){
$http.get('/packing/scan.action').then(function(response){
callback(response.data);
});
};
return {
serverData: serverData
};
});
Application.controller('PackingScanController',function(initdata){
initdata.serverData(function(serverdata){
$scope.serverdata = serverdata;
});
});
<强> 2。第二种方式只需返回HTTP承诺,让控制器处理它。
Application.service('initdata',function($http){
var serverData = function(){
return $http.get('/packing/scan.action');
};
return {
serverData: serverData
};
});
Application.controller('PackingScanController',function(initdata){
initdata.serverData().then(function(response){
$scope.serverdata = response.data;
});
});
3.您还可以返回serverData promise,而不是返回http响应承诺。
Application.service('initdata',function($http){
var serverData = function() {
var defer = $q.defer();
$http.get('/api/ponies').then(function(response) {
defer.resolve(response.data);
});
return defer.promise;
};
return {
serverData: serverData
};
});
Application.controller('PackingScanController',function(initdata){
initdata.serverData().then(function(response){
$scope.serverdata = response.data;
});
});