我的问题是,页面加载,当$ routeChangeSuccess事件触发时,从AJAX收到的数据可能还没有准备好。换句话说,我在事件处理程序和AJAX之间存在竞争条件。
当页面加载事件触发时,如何确保此数据存在。
这是一个证明问题的小提琴:http://jsfiddle.net/ajrt4/3/
我的场景:我有一个选择框,由$http
AJAX调用收到的数据填充。此选择框用于导航表示用户可以选择然后转到的一组路线。因为选择框需要让所选选项始终反映其当前路由,所以我在$routeChangeSuccess
事件上使用事件处理程序来更改所选的下拉菜单,当用户在浏览器中使用后退和前进按钮时。
以下是我在控制器中的示例:
$http.get('getData').success(function(data) {
// Sets the dropdown menu data
$scope.data = data;
});
$scope.$on("$routeChangeSuccess", function(event, currentRoute){
// Set the selected option here based off the route
if (typeof $scope.selected == 'undefined') {
for (var i = 0; i < $scope.data.length; i++) {
if ($scope.data[i].name == $routeParams.name) {
$scope.selected = $scope.data[i]; // sets the current selection based off the route parameter
return;
}
}
}
});
查看:
<select ng-model="selected" ng-options="option as option.name for option in data"></select>
收到的数据只需加载一次,因此我不需要或想要在resolve
上使用$routeProvider
,因为这与另一个控制器和视图一起使用。这也意味着我不会在事件处理程序中嵌套AJAX调用并冗余地获取数据。我认为可以解决这个问题的方法是使用Angular的$q
promise API,但不知道如何使用。
答案 0 :(得分:0)
虽然,Angular或事件可能不是最正确的方法,但我在这些场景中通常做的是将事件处理程序注册代码放入.then块中。 在您的情况下,$ http服务返回一个承诺,您可以执行以下操作
$http.get('getData').then(function(data) {
// Sets the dropdown menu data
$scope.data = data;
$scope.$on("$routeChangeSuccess", function(event, currentRoute){
...
}
});
但是又一次......你正在使用实际上相同的成功。问题是为什么不将处理程序注册放在成功块中。