Loading data, please wait…

W wielu swoich projektach pisanych w Angular.js nie jeden z Was (tak i ja) trafił pewnie na problem zapisania kilku informacji po stronie backednowej, a jednocześnie nie pozwolenie użytkownikowi w tym samym czasie wykonać dodatkowych operacji, które mogłyby zniwelować prawidłowość zapisu danych. Myślę jednak że każdy z Was trafił na problem dłuższego wczytywania danych i poinformowania o tym użytkownika. Jak sobie z takim problemem poradzić? 

Ja w takich przypadkach stosowałem okno modalne, które po zliczeniu czy wszystkie odpowiedzi wróciły samo się zamykało. Nie było to najlepsze rozwiązanie, ale niemniej skuteczne, choć nie będę ukrywał, że mało wygodne i uniwersalne. Szczególnie, że gdy chciałem pokazać uzytkownikowi jakie dane wczytuję lub zapisuję to problem znacznie mi się komplikował.

Ostatnio korzystając w swoim projekcie z Bootstrapa 3 i Angular.js stworzyłem mały mechanizm (może nie idealny), ale na tyle skuteczny, że bardzo mi się spodobał i postanowiłem się nim z Wami podzielić. W prosty sposób pozwala on rozwiązać wszystkie powyzsze problemy.

Zaznaczenie_004.jpg

Cały pomysł opiera się na następujących założeniach. Istnieje kontroler MessageCtrl, który nasłuchuje zdarzenia Message:addMsg.

$scope.$on('Message:addMsg', function(event, obj){
$scope.messages.push(obj);
$scope.openModal();
});

Zdarzenie to ma na celu dodać do tablicy message, kolejnej wiadomości i otworzyć okno modalne, które wyswietli pierwszą wiadomość z listy messages. Rozgłoszenie tego zdarzenia może wyglądać następująco:

var message = {
title: 'Środki trwałe'
,msg: 'Zapisuję dane. Proszę czekać...'
};
$rootScope.$broadcast('Message:addMsg', message);

Dodatkowo w kontrolerze znajduje się drugie zdrazenie Message:delMsg.

$scope.$on('Message:delMsg', function(event, obj){
$scope.messages.splice($scope.messages.indexOf(obj), 1);
if($scope.messages.length == 0)
{
$scope.closeModal();
}
});

Jego zadaniem jest nasłuchiwanie czy nie należy usunąć wiadomości z kolejki messages. Jeśli odnajdzie szukane powiadomienie, to usuwa je i zaczyna wyświetlać następne w kolejce, a jeżeli kolejka jest pusta to zamyka okno.

Ot i cały pomysł. Jak pisałem nie jest on idealny, ale działa 🙂 i mi on wystarcza, stąd myślę, że i Wam się przyda.

Poniżej zamieszczam cały kod kontrolera i pliku html

Plik message.html wygląda następująco:

<div ng-controller="MessageCtrl" id="modal-message" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">{{messages[0].title}}</h4>
</div>
<div class="modal-body">
{{messages[0].msg}}
</div>
</div>
</div>
</div>

Natomiast kontroler wygląda nastepująco:

function MessageCtrl($scope, $rootScope){
// lista powiadomień $scope.messages = [];
// ustawienie parametrów okna modalnego tak by nie było zamykane
// klawiszem ESC ani kliknieciem w tło angular.element('#modal-message').modal({ backdrop: 'static' ,keyboard: false ,show: false })
// otwiera okno modalne $scope.openModal = function(){ angular.element('#modal-message').modal('show'); }
// zamyka okno modalne $scope.closeModal = function(){ angular.element('#modal-message').modal('hide'); } $scope.$on('Message:addMsg', function(event, obj){ $scope.messages.push(obj); $scope.openModal(); }); $scope.$on('Message:delMsg', function(event, obj){ $scope.messages.splice($scope.messages.indexOf(obj), 1); if($scope.messages.length == 0) { $scope.closeModal(); } }); } MessageCtrl.$inject = ['$scope', '$rootScope'];

Powyższy mechanizm można dowolnie modyfikować i wykorzystywać na różne sposoby. W moim przypadku po drobnych modyfikacjach zrobiłem z tego mechanizm informujący użtkownika o zakończeniu jego sesji i konieczności ponownego zalogowania.

Zaznaczenie_003.jpg

Loading data, please wait…
Przewiń do góry