Skip to content

Instantly share code, notes, and snippets.

@christianalfoni
Last active October 5, 2017 22:48
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christianalfoni/8b01aa5dbe9d48e8e7bd to your computer and use it in GitHub Desktop.
Save christianalfoni/8b01aa5dbe9d48e8e7bd to your computer and use it in GitHub Desktop.
Angular JS state services for scalable applications
angular.module('app', [])
// We define a service state
.service('AppState', function ($rootScope) {
// We define a namespace for our application state and
// make it available as a variable for conveniance
var app = $rootScope.app = {};
// We define an application state
app.hasJoined = false;
// We return methods that can mutate our application
// state
return {
join: function () {
// When emitting an event from a state service it will only
// reach other state services as they listen to events on
// the $rootScope
$rootScope.$emit('join', 'anonymous');
// We can easily change state by pointing to our
// variable
app.hasJoined = true;
}
};
})
// We define a second service state
.service('MessagesState', function ($rootScope) {
// Again we create a namespace and a variable for
// conveniance
var messages = $rootScope.messages = {};
// We add an array of message as a state
messages.list = [];
// We listen to a 'join' event so that we can react
// to a state change on our "AppState"-service
$rootScope.$on('join', function (event, name) {
messages.list.push('Welcome ' + name);
});
return {
addMessage: function(message) {
messages.list.unshift(message);
// Broadcasting a message from a state will reach all controllers,
// letting them react to state changes in state services
$rootScope.$broadcast('message');
},
removeMessage: function removeMessage (index) {
messages.list.splice(index, 1);
}
};
})
// Our controller
.controller('AppCtrl', function ($scope, AppState, MessagesState, $timeout) {
// Properties added to $scope in controllers are only for that controller.
// To change state in the application you have to point to a method in those
// services
$scope.newMessage = '';
$scope.messageAdded = false;
// Here we point directly to a method in "AppState"
$scope.join = AppState.join;
// We listen to an event passed from a service, triggering a
// function
$scope.$on('message', function () {
$scope.messageAdded = true;
$timeout(function () {
$scope.messageAdded = false;
}, 1000);
});
// Here we also reset the internal state of the controller after
// calling a "MessagesState"-service method
$scope.addMessage = function () {
MessagesState.addMessage($scope.newMessage);
$scope.newMessage = '';
};
$scope.removeMessage = MessagesState.removeMessage;
});
<!DOCTYPE html>
<html>
<head></head>
<body ng-app="app">
<div ng-controller="AppCtrl">
<form ng-submit="addMessage()">
<input type="text" ng-disabled="!app.hasJoined" ng-model="newMessage"/>
</form>
<button ng-disabled="app.hasJoined" ng-click="join()">Join</button>
<ul ng-class="{'new-message': messageAdded}">
<li ng-repeat="message in messages.list">
{{message}} <button ng-click="removeMessage($index)">clear</button>
</li>
</ul>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment