var app = angular.module('app', []);
app.directive('someDirective', ['$log', 'someService', function($log, someService){
return {
restrict: 'A',
controllerAs: 'someDirective',
controller: function($scope, $element){
// a local method bound to "this"
var doSomething = (function doSomething(someData){
$log.log('Using the ctrl: ' + this.someVar);
$log.log('Does something with ' + someData);
}).bind(this);
// a local method not bound to "this"
function doAnotherThing(someData){
$log.log('Using the ctrl: ' + vm.someVar);
$log.log('Does another thing with ' + someData);
}
// a local method bound to "this"
var thingOne = (function thingOne(withData){
$log.log('Using the ctrl: ' + this.someVar);
$log.log('Thing One with data: ' + withData);
}).bind(this);
// a local method not bound to "this"
function thingTwo(withData){
$log.log('Using the ctrl: ' + vm.someVar);
$log.log('Thing Two with data: ' + withData);
}
// a local method not bound to "this"
function thingThree(withData){
$log.log('Using the ctrl: ' + vm.someVar);
$log.log('Thing Three with data: ' + withData);
}
var vm = this;
vm.someVar = 5;
// set async events
//can be 3 diff methods: success, error and notify
// for this demo we use the same method
var unsetDoSomething = someService.setAsyncListener('doSomething', doSomething, doSomething, doSomething);
var unsetDoAnotherThing = someService.setAsyncListener('doSomething', doAnotherThing, doAnotherThing, doAnotherThing);
// set sync events
someService.setSyncListener('lotsOfThings', thingOne);
someService.setSyncListener('lotsOfThings', thingTwo);
someService.setSyncListener('lotsOfThings', thingThree);
// clear sync events from the service to prevent memory leak
$element.on('$destroy', function(){
// unset sync events
someService.unsetSyncListener('lotsOfThings', thingOne);
someService.unsetSyncListener('lotsOfThings', thingTwo);
someService.unsetSyncListener('lotsOfThings', thingThree);
unsetDoSomething();
unsetDoAnotherThing();
});
}
}
}]);
app.service('someService', ['$q', '$log', function($q, $log){
function unsetAsyncListener(){
if (!this.promisesArray){
return;
}
var promisesArray = this.promises;
var unsetIndex = promisesArray.indexOf(this.pending);
promisesArray.splice(unsetIndex, 1);
this.pending = null;
this.promisesArray = null;
}
var asyncListeners = {}; //holds the listeners
var syncListeners = {};
var myService = {
setAsyncListener: function setAsyncListener(name, resolve, reject, notify){
if (!angular.isDefined(asyncListeners[name])){
asyncListeners[name] = $q.defer();
}
asyncListeners[name].promise.then(resolve, reject, notify);
return unsetAsyncListener.bind({
promisesArray: asyncListeners[name].promise.$$state.pending,
pending: asyncListeners[name].promise.$$state.pending[asyncListeners[name].promise.$$state.pending.length-1]
});
},
setSyncListener: function setSyncListener(name, callback){
if (angular.isUndefined(syncListeners[name])){
syncListeners[name] = [];
}
syncListeners[name].push(callback);
},
unsetSyncListener: function unsetSyncListener(name, callback){
if (angular.isUndefined(syncListeners[name])){
return;
}
// get the index and splice the listener
var index = syncListeners[name].indexOf(callback);
syncListeners[name].splice(index, 1);
},
method1: function needsToDoSomethingWithSomeData(someData){
// runs "doSomething" in the directive
asyncListeners.doSomething.notify(someData);
},
aVeryCoolAction: function needsToDoLotsOfThings(withData){
for (var i = 0; i < syncListeners.lotsOfThings.length; i++){
syncListeners.lotsOfThings[i](withData);
}
}
}
return myService;
}]);
app.controller('MainCtrl', ['$scope', 'someService', function ($scope, someService) {
var vm = this;
vm.doSomething = function(){
someService.method1(Math.random());
someService.aVeryCoolAction(Math.random());
}
}]);
.grid {
width: 600px;
}
.hovered{
outline: red 2px solid;
}
<!doctype html>
<html ng-app="app">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.js"></script>
<link rel="stylesheet" href="main.css" type="text/css">
</head>
<body>
<div ng-controller="MainCtrl as ctrl">
<button ng-click="hide = !hide">Hide</button>
<button ng-if="!hide" some-directive ng-click="ctrl.doSomething()">Do Something</button>
</div>
<script src="app.js"></script>
</body>
</html>