我一直在做一些谷歌搜索,但我找不到有效的解决方案。
我正在使用AngularJS 1.5.5和.NET Web API 2来构建Web应用程序,我很想隐藏firstpass
元素,直到所有结算都在路由上完成。
我正在尝试使用ng-view
和$routeChangeStart
在索引html中使用的$routeChangeSuccess
上设置变量,以显示加载指示符并隐藏内容,直到变量是$rootScope
。
这是routeChange属性的路由代码:
false
这是我使用_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;
});
}]);
变量的html:
$loadingRoute
我知道有很多文章涉及这个,但似乎没有一个在我的案例中。路由更改开始时,<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>
会按预期设置为true,如果我在$loadingRoute
标记之前将{{$loadingRoute}}
添加到HTML,我会看到。但是,在<section></section>
解决之前,$accountResolver
会被触发,设置$routeChangeSuccess
这是意外的。
我的印象是$rootScope.$loadingRoute = false
只有在当前路线完成所有结算后才被解雇。
我做的事情在这里真的很明显吗?或者只是改变了Angular?
编辑:我还想补充一点,这种方法在以前的项目中有效,所以我真的不知道出了什么问题。我可以在每个页面控制器中手动设置$routeChangeSuccess
但感觉太脏而且不可维护。
编辑2:
$rootScope.$loadingRoute
答案 0 :(得分:1)
为了让解析器延迟路由更改,它应该返回一个promise。否则,路由更改会立即发生,这是在$routeChangeSuccess
的承诺解决之前触发accountService.getMyAccountData()
时发生的情况。
问题是$resource
方法(以及accountService.getMyAccountData()
)返回以异步方式填充数据的自填充对象。此数据的承诺以$promise
属性提供(请参阅the reference),因此它应该用于解析器:
$accountResolver: function (accountService) {
return accountService.getMyAccountData().$promise;
}
如果accountService
应该是accountResource
的纯粹基于承诺的包装器,那么更简洁的方法是从其方法返回一个promise:
getMyAccountData: function () {
return accountResource.getMyAccountData().$promise;
}