Сообщение о загрузке AngularJS/пожалуйста, подождите

Как я могу добиться следующего в AngularJS:

введите здесь описание изображения

Если у меня есть моя страница, на которой будут отображаться некоторые виджеты, и у каждого виджета есть кнопка с именем «Обновить». При нажатии кнопки содержимое этого виджета перезагружается с сервера. Пока контент перезагружается, я хочу показать пользователю сообщение в этом виджете, пожалуйста, подождите... с возможным эффектом затухания.

Как я могу добиться этого в AngularJS?

Я как бы учил о том, что для этой цели должна быть общая служба, а затем каким-то образом каждый контроллер виджета будет использовать эту службу или что-то в этом роде, может быть, также директиву, которая будет отображать фактическую загрузку/пожалуйста, подождите сообщение?

Каков ваш совет?

P.S. Также должно быть сообщение загрузки/подождите с исчезновением для всей страницы, когда маршрут меняется... например, переключение между страницами.


person David Dury    schedule 19.11.2014    source источник
comment
довольно легко достичь, используя ng-show или ng-class и логическую переменную для каждого виджета, например, в директиве   -  person charlietfl    schedule 19.11.2014


Ответы (3)


В моем недавнем проекте я использую https://github.com/cgross/angular-busy.

Очень хорошая вещь, все, что вам нужно сделать, это поместить свое обещание в $scope, а затем добавить атрибут cg-busy к вашему элементу, который должен иметь счетчик (очевидно, помимо регистрации модуля):

Контроллер:

$scope.myPromise = restangular.get('something',12).then(function(response) { ... })

HTML:

<div cg-busy="myPromise"></div>

Вы также можете настроить шаблон, который будет отображаться (включая счетчик и текстовое сообщение).

person Mateusz Jamiołkowski    schedule 19.11.2014

на github доступны реализации этого: angular-spinner или angular-sham-spinner. Прочтите этот БЛОГ в котором подробно описывается, как счетчик работает с angularjs

если вы хотите реализовать его самостоятельно, чтобы его можно было использовать повторно...

app.directive("spinner", function(){
    return: {
        restrict: 'E',
        scope: { enable: "=" },
        template: '<div class="spinner" ng-show="enable"><img src="content/spinner.gif"></div>'
    }
});

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

person harishr    schedule 19.11.2014

Как резко указать, правильным путем будет директива, но нет необходимости, если вы хотите включить другую зависимость, вы можете сделать что-то вроде этого

  1. С помощью CssLoad можно создать красивую анимацию загрузки только с помощью CSS3 (изображения не требуются).

  2. Создайте директиву с функцией связывания, чтобы вы могли вызывать и останавливать анимацию в вашем контроллере угловым способом:

    .directive('appLoading', function(){
        return {
            restrict: 'E',
            templateUrl: 'template-file.html', // or template: 'template html code inline' Display none to the code is important so is not visible if youre not caling the methods
            replace: true,
            link: function(scope, elem) {
                scope.$on('app-start-loading', function(){
                    elem.fadeIn(); //asumming you have jquery otherwise play with toggleClass and visible and invisible classes
                });
                scope.$on('app-finish-loading', function(){
                    elem.fadeOut();
                });
            }
         }
     })
    
  3. Включите в свой html-код директиву: <app-loading></app-loading>

  4. Теперь все, что вам нужно сделать, это вызвать методы области в вашем контроллере следующим образом:

    $scope.$broadcast('начало загрузки приложения'); // для запуска анимации загрузки

    $scope.$broadcast('Завершение загрузки приложения'); // остановить анимацию

ПРИМЕЧАНИЕ. Если все ваши виджеты имеют общую область действия, загрузка может быть запущена во всех них.

person Strife86    schedule 19.11.2014
comment
Это выглядит действительно хорошо. Однако один вопрос: что вы подразумеваете под: if all widgets share a scope, the loading may be triggered in all of them ? Вы имеете в виду, что виджеты используют один и тот же контроллер? - person David Dury; 19.11.2014
comment
Не совсем так, все они могут иметь один и тот же контроллер, изолированный друг от друга, то есть, если я изменю параметр области действия в одном виджете, это не отразится на изменениях в остальных из них. - person Strife86; 20.11.2014
comment
если это ваш случай, вы можете добавить параметр для загрузки приложения, например ‹app-loading widget=1›, и использовать его для определения виджета, поэтому вам нужно будет отправить параметры в широковещательной передаче, если вы не знакомы с процедурой, скажите мне, поэтому я можно обновить мой ответ :) - person Strife86; 20.11.2014