Мерцание шаблона при изменении URL в Angular

#javascript #angularjs

#javascript #angularjs

Вопрос:

Я разрабатываю небольшое приложение с angular, и мне трудно решить проблему с мерцанием шаблона (показывает один шаблон, а затем сразу показывает другой), с которой я сталкиваюсь.

У меня есть <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, чтобы проверить, требует ли соответствующий маршрут входа пользователя в веб-приложение.

Ниже приведен определенный мной перехватчик, который проверяет, установлено ли свойство 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('/');
                }
              });
            }
         });
    });
  

Мерцание происходит, когда пользователь не аутентифицирован.

Ответ №1:

$routeProvider поддерживает свойство ‘resolve’, которое устраняет мерцание, задерживая изменение маршрута до тех пор, пока не будут разрешены все обещания от объекта 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
    }
  }).
  

Ответ №2:

Загляните в ngClock. Это может быть решением. https://docs.angularjs.org/api/ng/directive/ngCloak .В нем говорится, что

«Директива ngCloak используется для предотвращения кратковременного отображения углового html-шаблона браузером в его необработанном (нескомпилированном) виде во время загрузки вашего приложения. Используйте эту директиву, чтобы избежать нежелательного эффекта мерцания, вызванного отображением шаблона html «.

Ответ №3:

Как уже было сказано ранее: вы можете использовать ng-cloak.

но я думаю, что это не решит вашу проблему, потому что запрос выполняется впоследствии.

возможно, вы можете использовать модальный запрос для запроса учетных данных пользователя. я делаю что-то подобное, и это работает идеально. (модальное отображение с исчезновением, если пользователь не авторизован)

в вашем событии $routeChangeStart вы можете проверить, требуется ли авторизация. если нет, отправьте широковещательную рассылку loginRequired.

     $rootScope.$on('$stateChangeStart', function (event, nextState) {
            if (nextState.requireLogin) {
                event.preventDefault();
                $rootScope.$broadcast('auth-change', 'loginRequired', nextState.name);
            }
        });
  

logincontroller обрабатывает событие loginRequired и отображает модальное.