javascript - 在根级别显示加载指示器,直到所有路由解析完成

标签 javascript angularjs angularjs-ng-route

我已经在谷歌上搜索过这个问题,但找不到有效的解决方案。

我正在使用 AngularJS 1.5.5 和 .NET Web API 2 构建一个 Web 应用程序,我只想隐藏 ng-view元素,直到路线上的所有解析完成。

我正在尝试使用 $routeChangeStart$routeChangeSuccess$rootScope 上设置变量用于索引 html 中显示加载指示器并隐藏内容,直到变量为 false .

这是我的routeChange属性的路由代码:

_app.config([
        '$routeProvider', '$httpProvider', '$provide',
        function ($routeProvider, $httpProvider, $provide) {
                    $routeProvider.when('/Account',
                    {
                        templateUrl: '/Content/js/areas/account/account.html',
                        controller: 'accountController',
                        resolve: {
                            $accountResolver: function (accountService) {
                                return accountService.getMyAccountData();
                            }
                        },
                        caseInsensitiveMatch: true
                    });
            $routeProvider.otherwise({ redirectTo: '404' });

        }
]);

_app.run(['$rootScope', '$location', '$window', '$q', 'authService',
        function ($rootScope, $location, $window, $q, authService) {
            $rootScope.$on("$routeChangeStart",
                function (e, curr, prev) {
                    $rootScope.$loadingRoute = true;
                });
            $rootScope.$on("$routeChangeSuccess",
                function (evt, next) {
                    $rootScope.$loadingRoute = false;
                });
            $rootScope.$on("$routeChangeError",
                function (evt, next) {
                    $rootScope.$loadingRoute = false;
                });
        }]);

这是我使用 $loadingRoute 的 html多变的:

<body class="ng-cloak" data-ng-app="wishlist" data-ng-controller="appController">
    <wl-header></wl-header>
    <preloader ng-if="$loadingRoute"></preloader>
    <section ng-view ng-if="!$loadingRoute" class="container ng-cloak"></section>
</body>

我知道有很多文章讨论了这个问题,但似乎没有一篇适合我的情况。 $loadingRoute正如预期的那样,当路线更改开始时设置为 true,如果我添加 {{$loadingRoute}} 我会看到这一点到 <section></section> 之前的 HTML标签。然而在$accountResolver之前解决后,$routeChangeSuccess被解雇,设置 $rootScope.$loadingRoute = false这是意想不到的。

我的印象是$routeChangeSuccess仅在当前路线上的所有解析完成后才被解雇。

我在这里做了一些明显错误的事情吗?或者 Angular 只是发生了变化?

编辑:我还想补充一点,这种方法在以前的项目中有效,所以我对出了什么问题感到非常困惑。我可以设置 $rootScope.$loadingRoute在每个页面 Controller 中手动操作,但这感觉太脏且无法维护。

编辑2:

_app.factory('accountService', [
        'accountResource',
        function (accountResource) {
            var _self = this;

            return {
                register: function (authData) {
                    return accountResource.register(authData);
                },

                getMyAccountData: function () {
                    return accountResource.getMyAccountData();
                }
            }
        }
]);

_app.factory('accountResource', [
        '$resource', 'rootUrl',
        function ($resource, rootUrl) {
            var api = rootUrl() + 'api/Account';
            return $resource(api,
            {},
            {
                register: {
                    method: 'POST',
                    url: '{0}/register'.format(api)
                },
                getMyAccountData: {
                    method: 'GET',
                    url: '{0}/GetMyAccountData'.format(api)
                }
            });
        }
    ])

最佳答案

为了让解析器延迟路由更改,它应该返回一个 promise 。否则,路由更改会立即发生,这就是在解决 accountService.getMyAccountData() 的 promise 之前触发 $routeChangeSuccess 时发生的情况。

问题是 $resource 方法(以及 accountService.getMyAccountData())返回异步填充数据的自填充对象。此数据的 promise 可作为 $promise 属性使用(请参阅 the reference ),因此它应该用于解析器:

$accountResolver: function (accountService) {
  return accountService.getMyAccountData().$promise;
}

如果 accountService 应该是 accountResource 的纯粹基于 promise 的包装器,则更简洁的方法是从其方法返回 promise :

getMyAccountData: function () {
    return accountResource.getMyAccountData().$promise;
}

关于javascript - 在根级别显示加载指示器,直到所有路由解析完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43100808/

相关文章:

javascript - 避免 jQuery 中的巨大级联?

javascript - AngularJS - 使用 $resource - 为什么我的控制台日志中有这么多条目?

Angularjs 路由参数不起作用

angularjs - 加载新路线后, Controller 的旧实例仍在运行

javascript - 将数组映射到 Typescript/Angular 中的对象

angularjs - 如何在不使用 yeoman 的情况下使用 Node.js 在 Heroku 中托管 AngularJS 应用程序?

javascript - 动态添加标签到正文

javascript - 使用 Angular/PHP 将 JSON 对象插入 MySQL 表

javascript - 使用 Autolinker.js 排除特定链接

javascript - 当绑定(bind)到 AngularJS 中的函数时,幕后会发生什么