当$ routeChangeSuccess事件处理程序触发时,需要准备好来自$ http get on page load的返回数据

时间:2014-06-11 18:39:46

标签: angularjs angular-routing angular-http

我的问题是,页面加载,当$ 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,但不知道如何使用。

1 个答案:

答案 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){
    ...
    }
});

但是又一次......你正在使用实际上相同的成功。问题是为什么不将处理程序注册放在成功块中。