Angularjs:如何在使用'解决'在$routeProvider中
Angularjs: How to display loading-icon when using 'resolve' in $routeProvider?
以下代码通过服务读取,并在网页上显示特定"页面类别"(字符串)的"页面"对象列表。使用$routeProvider.when()中的解析对象属性,我可以推迟更新视图,直到新值准备好为止。
两个问题:
-
当要求一个新的页面列表时,我想显示一个加载图标。当从服务器开始读取(并且应该显示加载图标)时,我如何(以非黑客的方式)检测事件?我想我可以在服务中做一些类似$('.pages loading icon').show()的事情,但发现它太依赖gui了,太放在服务中了。
-
当新值准备好时,我希望旧值淡出,新值淡出。什么是"棱角分明"的方法?我曾尝试使用$watch在控制器中执行此操作,但这会导致在淡出开始前不久显示新值。
代码:
app.js:
$routeProvider.when('/:cat', { templateUrl: 'partials/view.html', controller: RouteCtrl, resolve: RouteCtrl.resolve});
controllers.js:
function RouteCtrl($scope, $routeParams, pages) {
$scope.params = $routeParams;
$scope.pages = pages;
}
RouteCtrl.resolve={
pages: function($routeParams, Pages){
if($routeParams.hasOwnProperty('cat')){
return Pages.query($routeParams.cat);
}
}
}
services.js:最后读取的页面存储在currentPages中,其类别存储在lastCat中。
factory('Pages', function($resource, $q, $timeout){
return {
res: $resource('jsonService/cat=:cat', {}, {
query: {method:'GET', params:{cat:'cat'}, isArray:true}
}),
lastCat: null,
currentPages: null,
query: function(cat) {
var res = this.res;
if(cat != this.lastCat){
var deferred = $q.defer();
var p = res.query({'cat':cat}, function(){
deferred.resolve(p);
});
this.lastCat = cat;
this.currentPages = deferred.promise;
}
return this.currentPages;
}
};
})
view.html
<ul >
<li ng-repeat="page in pages">
<a href="#{{params.cat}}/{{page.slug}}">{{page.title}}</a>
</li>
</ul>
不确定这是否会在您的代码中工作,因为您有$resource集成。但研究角度事件可能是值得的:$routeChangeStart
和$routeChangeSuccess
。
在html:中
<span ng-show="isViewLoading"> loading the view... </span>
在控制器中(定义了上面html的范围):
$scope.isViewLoading = false;
$scope.$on('$routeChangeStart', function() {
$scope.isViewLoading = true;
});
$scope.$on('$routeChangeSuccess', function() {
$scope.isViewLoading = false;
});
$scope.$on('$routeChangeError', function() {
$scope.isViewLoading = false;
});
angular的路由系统似乎有点有限。。
这为我解决了问题:
http://www.bennadel.com/blog/2420-Mapping-AngularJS-Routes-Onto-URL-Parameters-And-Client-Side-Events.htm
此外,关于触发两次的事件:如果您设置了一条路线,则映射到"a/b/c"角度会自动设置另一条路线、"a/b/c/"(带尾部斜线)重定向到第一条路线(反之亦然),并同时触发两次事件。我只是测试是否存在路由参数。
关于路由系统的有限条件:有这种来自角度的拉力,以扩展其能力。
您将希望使用$rootScope
,因为监视控制器的$scope
仅限于该控制器,而且您正在从一个视图(一个控制器)切换到另一个视图。因此,让一个代码适合所有代码是有意义的。
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams){ ... })
在该功能中,设置$rootScope.isLoadingState
,它将显示您的装载指示器。
然后使用
$rootScope.$on('$stateChangeSuccess',
function(event, toState, toParams, fromState, fromParams){ ... })
取消设置该变量。
此处完整参考
您还可以使用ng-show指令。只需检查您的模型是否为空,并显示如下DOM子集:
<!-- model not ready -->
<div style="width: 200" ng-show="lines == ''">
<div class="progress progress-striped active">
<div class="bar" style="width: 0%;"></div>
</div>
</div>
<!-- your model code -->
<ul class="nav nav-tabs nav-stacked">
<li ng-repeat="line in lines">
{{line.Id}}
</li>
</ul>
我喜欢'ng-show'
。。。但是Angular UI项目的'ui-if'
更好。。由于从DOM中删除HTML代码。。。
<span ui-if = "isViewLoading"> loading the view... </span>
_e
您可以创建一个指令,该指令将根据您在服务调用前后发送的广播显示,您可以将其放在$rootScope上。因此,如果您正在调用一个工厂来处理发出的通用POST/GET调用,那么就在调用之前,您可以在$rootScope上调用一个函数,例如"$rootScope.startLoading()",当它完成调用"$rootScope.doeLoading())"时,这些方法中的每一个都会广播一个事件,供您根据指令进行操作。然后,您只需处理捕获事件的指令"scope.$on("startLoading",func(
这样你就可以有一个很好的通用加载覆盖。
- 如何解决Yii中的页面刷新问题
- 测试Angular Service解决错误回调中的promise
- 如何解决Access Control Allow Origin错误
- 如何解决这种情况下的非法调用类型错误
- 简单的ES6承诺问题-交换解决和拒绝参数
- 可以转换显示属性吗?如果没有,什么'这是最好的解决方案
- iPad虚拟键盘-哪一个-javasctript解决方案
- 在ES6 Promise中,我应该在解决/拒绝之前使用return吗
- 如何解决“;错误所请求的URL返回500-内部服务器错误”;
- 如何逃离<脚本>jquery html()中的标记.我使用了innerHTML和outerHTML来解决这个
- 如何解决'窗口未定义'终端上的节点JS出错
- Angularjs:如何在使用'解决'在$routeProvider中
- 可以't解决Javascript错误
- AJAX HTTP基本身份验证解决方案
- 为什么不'我的窗口滚动事件根本没有启动.其他答案没有解决问题
- 如何解决此错误
- 在chrome web商店中打开时,是否有允许执行内容/后台脚本的解决方案
- CORS故障无法解决jquery,laravel5.2
- AngularJS routeprovider赢得'Don’我什么都不做
- 使用'解决'以等待routeProvider中的查询结果