我想尽可能地限制我的AngularJS应用程序中的“闪烁”.我使用resolve:从路由器(与ngRouter和ui-router一起工作)加载数据,以便在更改路由之前显示我的页面所需的一切.
常见例子:
.state('recipes.category',{ url: '/:cat',templateUrl: '/partials/recipes.category.html',controller: 'RecipesCategoryCtrl as recipeList',resolve: { category: ['$http','$stateParams',function ($http,$stateParams) { return $http.get('/recipes/' + $stateParams.cat).then(function(data) { return data.data; }); }] } });
现在我的RecipesCategoryCtrl控制器可以加载类别,承诺将直接解决.
有没有办法将加载代码直接嵌入我的控制器中?或者其他地方更“干净”?我不喜欢在路线定义中有太多逻辑……
就像是:
.state('recipes.category',resolve: 'recipeList.resolve()' // something related to RecipesCategoryCtrl and "idiomatic" AngularJS });
解决方法
也许这不是你想要的,但你可以使用以下方法将一些逻辑从路由器移动到控制器:
//prepare content $scope.$on('$viewContentLoading',function(event) { //show a progress bar whatever //fetch/request your data asynchronously //when promise resolves,add your data to $scope }); //remove spinning loader when view is ready $scope.$on('$viewContentLoaded',function(event) { //remove progress bar });
基本上,用户首先被发送到页面,然后加载动态内容,然后显示整页.
这可能完全偏离主题,但我正在使用这种方法并且工作正常.首先显示新视图然后获取数据也是一种很好的做法.有一个非常好的视频here解释了原因.该视频是关于带有Phonegap的SPA,但有很多关于SPA的提示.有趣的部分(针对这个具体案例)
是大约1小时1分钟.
编辑:如果$viewContentLoading没有被触发,请查看here.您可能需要将所有逻辑放在$viewContentLoaded中
这就是我目前正在做的事情:
$scope.$on('$viewContentLoaded',function(event) { //show loader while we are preparing view notifications.showProgressDialog(); //get data getData().then(function(data) { //bind data to view $scope.data = data; //remove spinning loader as view is ready notifications.hideProgressDialog(); }); });
$scope.data = data我仍然不是100%满意;好像我的数据对象很大,我可能会在与视图绑定完成之前隐藏进度对话框,因此可能会出现一些闪烁.解决方案是使用自定义指令处理范围.$last,参见this answer(即使绑定到$stateChangeSuccess就足够了,看看here)
这是ui-router在更改状态/视图时的当前工作方式:
> $viewContentLoading获得广播>已解决“解析”部分下的依赖关系> Controller实例化并解决注入的依赖项.> $viewContentLoaded被发出.>控制器对$viewContentLoaded做出反应(当它被设置为委托时,当然会调度这些事件).