2013-09-18 2 views
3

Я использую AngularJS и ngProgress для отображения загрузочной панели, подобной YouTube, в верхней части моего сайта.ngПрограмма загрузки при каждой загрузке страницы

Бар запускается, затем новые данные загружаются через ajax, и как только запрос завершен, панель завершается.

Пример:

var TestCtrl = function($scope, $location, Tests, ngProgress) 
{ 
    // start progressbar 
    ngProgress.start(); 

    $scope.tests = Tests.query(
     function() 
     { 
      // end progressbar 
      ngProgress.complete() 
     } 
    ); 
}; 

Теперь мой вопрос: Как я могу интегрировать этот принцип выше, в порядке вещей, так что я не должен повторять код для каждого отдельного контроллера?

+1

Бросьте его в службе, и ввести услугу в каждый контроллер, который нуждается в его функциональности. –

ответ

0

Вы, видимо, уже есть Tests обслуживание. Переопределите его так, чтобы в него было введено ngProgress, и Tests всегда звоните ngProgress.start() и ngProgress.complete() для вас в query.

2

Вы можете использовать службу, которая контролирует ngProgress (действует как обертка поверх нее) и прослушивает изменения в URL-адресе.

  • Каждый раз, когда изменения URL событие $locationChangeSuccess транслируется (подробнее на $location), который мы могли бы слушать, чтобы вызвать ngProgress.start()
  • Однако мы не знаем, когда она завершена (мы не можем есть бар на верхняя загрузка навсегда), поэтому нам нужно называть ngProgress.complete() явно в наших контроллерах. Или мы могли бы предположить, что наши функции асинхронного ввода могут занять около 5 секунд и вызвать ngProgress.complete() с использованием таймера в нашей службе обертки
  • Когда загрузочная панель уже видимый, и есть изменение в URL-адресе, нам нужно сбросить статус бара кал лин ngProgress.reset()

Вы можете использовать следующий подход к решению этих проблем:

angular.module('myApp').factory('Progress', function (ngProgress) { 
    var timer; 
    return { 
     start: function() { 
      var me = this; 
      // reset the status of the progress bar 
      me.reset(); 
      // if the `complete` method is not called 
      // complete the progress of the bar after 5 seconds 
      timer = setTimeout(function() { 
       me.complete(); 
      }, 5000); 
     }, 
     complete: function() { 
      ngProgress.complete(); 
      if (timer) { 
       // remove the 5 second timer 
       clearTimeout(timer); 
       timer = null; 
      } 
     }, 
     reset: function() {    
      if (timer) { 
       // remove the 5 second timer 
       clearTimeout(timer); 
       // reset the progress bar 
       ngProgress.reset(); 
      } 
      // start the progress bar 
      ngProgress.start(); 
     } 
    }; 
}); 

Для прослушивания изменений в URL и показать прогресс бар мы могли бы использовать:

angular.module('myApp') 
    .run(function (Progress) { 
     $rootScope.$on('$locationChangeSuccess', function() { 
      Progress.start(); 
     }); 
    } 

сейчас мы можем вручную управлять полнотой строки состояния, введя услугу Progress и вызывая метод Progress.complete(), когда все наши асинхронные функции завершены (мы могли бы также c ontrol это от каких-либо услуг, что делает асинхронных вызовов):

angular.module('myApp') 
    .controller('SomeCtrl', function (Progress) { 
     setTimeout(function() { 
      Progress.complete(); 
     }, 2000); 
    }); 
1

Вот пример использования Interceptor:

.factory('interceptorNgProgress', [ 
    'ngProgressFactory', function (ngProgressFactory) { 

var complete_progress, getNgProgress, ng_progress, working; 
ng_progress = null; 
working = false; 

getNgProgress = function() { 

    if(!ng_progress) { 

     ng_progress = ngProgressFactory.createInstance(); 

     return ng_progress; 
    } 

    return ng_progress; 
}; 

complete_progress = function() { 
    var ngProgress; 
    if (working) { 
     ngProgress = getNgProgress(); 
     ngProgress.complete(); 
     return working = false; 
    } 
}; 

return { 
    request: function(request) { 
     var ngProgress; 
     ngProgress = getNgProgress(); 
     if (request.url.indexOf('.html') > 0) { 
      return request; 
     } 
     if (!working) { 
      ngProgress.reset(); 
      ngProgress.start(); 
      working = true; 
     } 
     return request; 
    }, 
    requestError: function(request) { 
     complete_progress(); 
     return request; 
    }, 
    response: function(response) { 
     complete_progress(); 
     return response; 
    }, 
    responseError: function(response) { 
     complete_progress(); 
     return response; 
    } 
} 
}]) 

.config(function ($httpProvider) { 
    $httpProvider.interceptors.push('interceptorNgProgress'); 
}); 
+0

Спасибо, Zeecher.Это действительно сработало для меня. – maniempire

Смежные вопросы