我正在为我的角度应用程序使用 ui-router。我有一些包含图像的视图。我希望角度加载栏也可以在这些图像完成加载时进行跟踪。或者更一般地说,直到视图完成渲染。
当我偶然发现那篇关于如何使用 angularJS 进行 SEO 的帖子时,它表明我们必须为每个“页面”创建静态 html 快照并将它们提供给搜索引擎机器人,以便它们可以被抓取。为此,我们必须自己使用无头浏览器爬取应用程序中的所有页面,并将 html 存储到将要提供的文件中。但是,由于 Angular 必须通过 ajax 和所有方式加载视图,我们必须等待页面加载完毕,然后才能存储无头浏览器 html 的内容。否则我们会得到带有空视图的空 html。
我写了一个小脚本,可以检查我们视图的就绪状态。当 $rootScope.status 属性等于 'ready' 时,我知道我可以存储我的无头浏览器的 html,因为它已完成加载。
var app = angular.module("app", ["ui.router", 'ngAnimate','angular-loading-bar','angular-images-loaded','angular-google-analytics']);
app.run(['$rootScope', function($rootScope){
$rootScope.loadingCount = 0;
$rootScope.changeSuccess = false;
$rootScope.ready = function(){
$rootScope.loadingCount--;
if (($rootScope.loadingCount == 0) && ($rootScope.changeSuccess == true)){
$rootScope.status = 'ready';
}
};
$rootScope.loading = function(){
$rootScope.loadingCount++;
$rootScope.status = 'loading';
};
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
$rootScope.loadingCount = 0;
$rootScope.changeSuccess = false;
});
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
$rootScope.changeSuccess = true;
});
$rootScope.$on("$viewContentLoading", function(){
$rootScope.loadingCount++;
});
$rootScope.$on("$viewContentLoading", function(){
$rootScope.loadingCount--;
});
}]);
然后,在我们的每个控制器中,我们必须调用
$rootScope.loading();
当控制器准备好时
$rootScope.ready()
有了这个,我们就可以检查我们所有的控制器是否都渲染了他们的视图。它现在不是超级优雅,但它可以完成工作。
该脚本可以很好地与 angular-loading-bar 集成,因为它跟踪整个应用程序的准备情况。进度条可能是该进度的指示器。这样做的缺点是它与 angular-loading-bar 跟踪 XHR 请求的自然行为有冲突。
例如,在我的控制器中,我使用这个:
app.controller("WorksController", [
"$scope", "cfpLoadingBar",
function ($scope, cfpLoadingBar) {
cfpLoadingBar.start();
$scope.imgLoadedEvents = {
always: function () {
cfpLoadingBar.complete();
}
};
}
]);
此代码应直接在跟踪视图准备情况的 $rootScope 脚本中迁移。
$rootScope.$watch('status', function(newValue, oldValue){
if (newValue == 'loading'){ cfpLoadingBar.start() }
else if (newValue == 'ready') { cfpLoadingBar.complete() }
})
不过,angular-progress-bar 仍然在后台工作。我激活了 XHR 拦截器。但是,如果 XHR 请求在图像加载之前完成,即使视图尚未完成,进度条也会消失。同样,如果在 XHR 请求完成之前加载了图像,则进度条会消失。
如何将 angular-loading-bar 的 XHR 拦截功能与此视图准备拦截功能集成?