我有几个屏幕和控制器依赖来自服务器的数据。因此,我想通过路由器解析功能来解决数据依赖性,让它在渲染屏幕之前注意所有数据都可以通过promises获得。但是,我不确定我是否正确理解了用法,因为以下示例似乎不起作用。为什么呢?
angular.module('app',['ngRoute'])
.service('Data1', function ($q, $routeProvider, $http) {
var self = this;
this.fetch = function() {return $http.get('/json/data1',{id:$routeProvider.id})}
}
.service('Data2', function ($q, $routeProvider, $http) {
var self = this;
this.fetch = function() {return $http.get('/json/data2',{id:$routeProvider.id})}
}
.config(function($routeProvider){
§routeProvider.when('/:id',{
controller:'TestCtrl',
templateUrl:'template.html',
resolve: {
data1: function (Data1) { return Data1.fetch(); },
data1: function (Data2) { return Data2.fetch(); }
}
});
})
.controller('TestCtrl', function($location, $routeParams, $http, data1,data2) {
console.log(data1);
console.log(data2);
});
答案 0 :(得分:1)
以下是如何正确使用resolve
和$routeProvider
的示例。首先,我定义了两个工厂,就像你在那里一样,然后在我的配置中,我设置了一条路线,我想从我的工厂注入数据。我告诉它我想要使用什么控制器,在这种情况下模板是非重要的。然后在解析下,我给它一个具有两个属性的对象,即someData
和someMoreData
。在这两个函数中,我注入data1
和data2
工厂以及$routeParams
,从工厂获取数据,然后返回数据。
在我的控制器定义中,我告诉它我要注入$scope
,然后我告诉它我想要注入另外两件事,这些是我在$routeProvider
中定义的解析属性。
有一点需要注意的是,如果您在工厂中进行实际的API调用,而您希望从中解析数据,则在解析数据之前页面将不会加载,控制器甚至不会启动,直到这些都是完成。所以你可能想提出一些加载动画的方法,StackOverflow上有很多关于如何做的例子。
angular.module('app.factories', [])
.factory('data1', ['$q', '$timeout', function($q, $timeout) {
return {
getData: function(id) {
var deferred = $q.defer();
var promise = deferred.promise;
$timeout(function() {
deferred.resolve('this is factory 1, id: ' + id);
}, 2000);
return promise;
}
};
}])
.factory('data2', ['$q', '$timeout', function($q, $timeout) {
return {
getData: function(id) {
var deferred = $q.defer();
var promise = deferred.promise;
$timeout(function() {
deferred.resolve('this is factory 2, id: ' + id);
}, 2000);
return promise;
}
};
}]);
angular.module('app', ['ngRoute', 'app.factories'])
.config(['$routeProvider',
function($routeProvider) {
$routeProvider
.when('/', {
controller: 'defaultCtrl',
template:'<a href="#/1">Go to route with parameter on it</a>'
})
.when('/:id', {
controller: 'testCtrl',
template: '<span ng-bind="string1"></span><br /><span ng-bind="string2"></span>',
resolve: {
someData: ['data1', '$route',
function(data1, $route) {
console.log('resolving someData');
return data1.getData($route.current.params.id).then(
function(response) {
return response;
});
}
],
someMoreData: ['data2', '$route',
function(data2, $route) {
console.log('resolving someMoreData');
return data2.getData($route.current.params.id).then(
function(response) {
return response;
});
}
]
}
});
}
])
.controller('defaultCtrl', function() { })
.controller('testCtrl', ['$scope', 'someData', 'someMoreData',
function($scope, someData, someMoreData) {
console.log('in route with id param');
$scope.string1 = someData;
$scope.string2 = someMoreData;
}
]);
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular-route.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div ng-view>
</div>
</body>
</html>
修改强> 修改它,以便你的工厂在他们自己的模块中,并作为依赖注入app模块,而不是在app模块本身,这是恕我直言倾向于更好的架构(大多数时候我给每个工厂它自己的模块,但为了简洁起见,我保持简单)