我正在开发一个带角度的小应用程序,我很难解决模板闪烁(显示一个模板,然后立即显示另一个模板)我面临的问题。
我的基本模板中定义了<ng-view>
标记和一些部分文件。
这是我的routeProvider
设置:
app.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: '/static/partials/login.html',
controller: 'LoginController',
requireLogin: false
}).
when('/login', {
templateUrl: '/static/partials/login.html',
controller: 'LoginController',
requireLogin: false
}).
when('/register', {
templateUrl: '/static/partials/register.html',
controller: 'RegisterController',
requireLogin: false
}).
when('/profile', {
templateUrl: '/static/partials/profile.html',
controller: 'ProfileController',
requireLogin: true
}).
otherwise({
redirectTo: '/'
});
}]);
正如您所看到的,我正在定义一个requireLogin属性来检查相应的路由是否要求用户登录到webapp。
以下是我定义的拦截器,用于检查是否设置了requireLogin属性,如果是,则询问服务器是否对用户进行了身份验证。如果用户未经过身份验证,则会将其重定向到登录页面。
app.run(function($rootScope, $location, $http) {
$rootScope.$on('$routeChangeStart' , function(event, current) {
if(current.requireLogin) {
$http.get('/authenticated').success(function(response){
if(!response.authenticated) {
$location.path('/');
}
});
}
});
});
当用户未经过身份验证时会发生闪烁。
答案 0 :(得分:8)
$ routeProvider支持&#39;解决&#39;属性,通过延迟路由更改来解决闪烁,直到解析对象的所有promise都已解决。 resolve属性可注入控制器功能。以下是其工作原理的示例:
when('/profile', {
templateUrl: '/static/partials/profile.html',
controller: function($scope, profile, loginInfo) {
$scope.data = profile.data;
$scope.loginInfo = loginInfo;
},
requireLogin: true,
resolve: {
profile: function($http) {
// return a promise
return $http({ method: 'GET', url:'/getProfile' });
},
loginInfo: function() {
// return an object literal
return { details: { ... } }
},
etc
}
}).
答案 1 :(得分:1)
查看ngClock。这可能是一个解决方案。 https://docs.angularjs.org/api/ng/directive/ngCloak。它声明
“ngCloak指令用于防止浏览器在加载应用程序时以原始(未编译)形式短暂显示Angular html模板。使用此指令可避免html模板显示导致的不良闪烁效应”
答案 2 :(得分:1)
如前所述:你可以使用ng-cloak。
但我认为这不会解决您的问题,因为请求会在之后发生。
也许你可以使用模态来询问用户的凭据。我做类似的事情,它的工作完美。 (如果用户未获得授权,则模式显示淡入)
在$ routeChangeStart事件中,您可以检查是否需要授权。如果没有,请发送loginRequired广播。
$rootScope.$on('$stateChangeStart', function (event, nextState) {
if (nextState.requireLogin) {
event.preventDefault();
$rootScope.$broadcast('auth-change', 'loginRequired', nextState.name);
}
});
logincontroller处理loginRequired事件并显示模态。