forked from angular-app/angular-app
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New API for the notification service, refactored the individual lists…
… into their own objects
- Loading branch information
1 parent
165f5d1
commit f5e9828
Showing
2 changed files
with
149 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,57 +1,141 @@ | ||
angular.module('services.notifications', []).factory('notifications', function ($rootScope) { | ||
angular.module('services.notifications', []); | ||
|
||
var notifications = { | ||
'GLOBAL' : [], | ||
'ROUTE' : [], | ||
'NEXT_ROUTE' : [] | ||
}; | ||
var notificationsService = {}; | ||
angular.module('services.notifications').factory('notifications', function ($rootScope) { | ||
|
||
// A factory to create a notification list object that manages its own notifications | ||
var createNotificationList = function() { | ||
var list = []; | ||
|
||
var notificationList = { | ||
// Create a new notification with a string message and optional type (defaults to 'info'). | ||
// The options can be used to attach custom fields to the notification | ||
// The notification will contain a remove method that can be used to remove itself from the list | ||
createNotification: function(message, type, options) { | ||
var notification = { | ||
message: message, | ||
type: type || 'info', | ||
remove: function() { | ||
notificationList.remove(notification); | ||
} | ||
}; | ||
return angular.extend(notification, options); | ||
}, | ||
|
||
// Remove a notification from this list that is matched by the matchNotificationFn function. | ||
remove: function(matchNotificationFn) { | ||
angular.forEach(list, function(notification, index) { | ||
if ( matchNotificationFn(notification) ) { | ||
list.splice(index, 1); | ||
} | ||
}); | ||
}, | ||
|
||
// Remove all the notifications from this list | ||
removeAll: function() { | ||
list.length = 0; | ||
}, | ||
|
||
// Push a notification to the end of this list | ||
push: function(notification) { | ||
list.push(notification); | ||
}, | ||
|
||
var clearMixIn = function(notification) { | ||
//TODO: do it better, without creating new function instances each time... | ||
notification.$clear = function() { | ||
notificationsService.clear(this); | ||
// Access the notifications in this list | ||
getAll: function() { | ||
return list; | ||
} | ||
}; | ||
return notification; | ||
|
||
return notificationList; | ||
}; | ||
|
||
$rootScope.$on('$routeChangeSuccess', function () { | ||
notifications.ROUTE.length = 0; | ||
|
||
notifications.ROUTE = angular.copy(notifications.NEXT_ROUTE); | ||
notifications.NEXT_ROUTE.length = 0; | ||
}); | ||
var notificationLists = {}; | ||
var includeInCurrent = []; | ||
var notificationsService = { | ||
// Returns a concatenated array of all the notifications from all the lists in the service | ||
all: function() { | ||
var notifications = []; | ||
angular.forEach(notificationLists, function(list) { | ||
notifications = notifications.concat(list.getAll()); | ||
}); | ||
return notifications; | ||
}, | ||
|
||
notificationsService.get = function(){ | ||
return [].concat(notifications.GLOBAL).concat(notifications.ROUTE); | ||
}; | ||
current: function() { | ||
var notifications = []; | ||
angular.forEach(includeInCurrent, function(listName) { | ||
notifications = notifications.concat(notificationLists[listName].getAll()); | ||
}); | ||
return notifications; | ||
}, | ||
|
||
notificationsService.clear = function(notification){ | ||
angular.forEach(notifications, function (notificationsByType) { | ||
var idx = notificationsByType.indexOf(notification); | ||
if (idx>-1){ | ||
notificationsByType.splice(idx,1); | ||
// Remove a notification from the lists of the service, matching it either by the object itself or by the message string | ||
remove: function(messageOrNotification) { | ||
var matchFn; | ||
if ( angular.isString(messageOrNotification) ) { | ||
matchFn = function(notification) { return notification.message === messageOrNotification; }; | ||
} else { | ||
matchFn = function(notification) { return notification === messageOrNotification; }; | ||
} | ||
}); | ||
}; | ||
angular.forEach(notificationLists, function(list) { | ||
list.remove(matchFn); | ||
}); | ||
}, | ||
|
||
notificationsService.clearAll = function(){ | ||
angular.forEach(notifications, function (notificationsByType) { | ||
notificationsByType.length = 0; | ||
}); | ||
}; | ||
// Remove all the messages from all the lists in the service | ||
removeAll: function(){ | ||
angular.forEach(notificationLists, function (list) { | ||
list.removeAll(); | ||
}); | ||
}, | ||
|
||
notificationsService.addFixed = function(notification) { | ||
notifications.GLOBAL.push(clearMixIn(notification)); | ||
}; | ||
// Push a notification to the specified list | ||
pushNotification: function(list, message, type, options) { | ||
list = notificationLists[list]; | ||
if ( angular.isDefined(list) ) { | ||
var notification = list.createNotification(message, type, options); | ||
list.push(notification); | ||
return notification; | ||
} else { | ||
throw new Error('"' + list + '"" is not a valid notification list.'); | ||
} | ||
} | ||
|
||
notificationsService.addRouteChange = function(notification) { | ||
notifications.ROUTE.push(clearMixIn(notification)); | ||
}; | ||
// addNotificationListToService (see below) will create a method on the service to push notifications to the list | ||
// For example, addNotificationListToService('CurrentRoute') will create notificationsService.pushCurrentRouteNotification(message, type, options) | ||
|
||
notificationsService.addNextRouteChange = function(notification) { | ||
notifications.NEXT_ROUTE.push(clearMixIn(notification)); | ||
}; | ||
|
||
function pushFunctionName(listName) { | ||
return 'push'+listName+'Notification'; | ||
} | ||
|
||
// Add and configure a new list in the notification service. | ||
function addNotificationListToService(name) { | ||
notificationLists[name] = createNotificationList(name); | ||
notificationsService[pushFunctionName(name)] = function(message, type, options) { return notificationsService.pushNotification(name, message, type, options); }; | ||
} | ||
|
||
function moveNotificationList(oldListName, newListName) { | ||
notificationsService[pushFunctionName(newListName)] = notificationsService[pushFunctionName(oldListName)]; | ||
notificationLists[newListName] = notificationLists[oldListName]; | ||
delete notificationsService['push'+oldListName+'Notification']; | ||
delete notificationLists[oldListName]; | ||
} | ||
|
||
addNotificationListToService('Sticky'); | ||
addNotificationListToService('CurrentRoute'); | ||
addNotificationListToService('NextRoute'); | ||
|
||
includeInCurrent.push('Sticky'); | ||
includeInCurrent.push('CurrentRoute'); | ||
|
||
// Rewire the CurrentRoute and NextRoute notification lists when the route changes | ||
$rootScope.$on('$routeChangeSuccess', function () { | ||
moveNotificationList('NextRoute', 'CurrentRoute'); | ||
addNotificationListToService('NextRoute'); | ||
}); | ||
|
||
return notificationsService; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters