var App = {};
App.Factory = function Parent() {
var subUid = -1;
var events = {};
var context = {};
var publish = function(subject, result) {
events[subject].subscribers.forEach(function(o) {
o.func.apply(this, [result]);
});
};
var sub = function(event, func) {
var token = (++subUid).toString();
if(typeof events[event] === 'object'){
events[event].subscribers.push({
token: token,
func: func
});
}else{
func.apply(this, ['is Undefined']);
}
return token;
};
var unsub = function(event, token) {
var removed = false;
events[event].subscribers.some(function(sub, i) {
if (sub && sub.hasOwnProperty('token') && sub.token === token) {
events[event].subscribers.splice(i, 1);
removed = true;
return removed;
}
});
return removed;
};
return {
addEvent: function addEvent(publisher) {
if (publisher) {
if (!events.hasOwnProperty(publisher)) {
events[publisher] = {
event: {
name: publisher,
publish: function perform(result) {
context[publisher] = result;
publish(publisher, result);
}
},
subscribers: []
};
}
console.log('new event: ' + events[publisher].event.name);
} else {
throw {
error: 'no name given'
};
}
},
subscribe: sub,
unsubscribe: unsub,
act: function(publisher, result) {
events[publisher].event.publish(result);
}
};
};
angular.module('app', []).config([
'$provide', function($provide) {
return $provide.decorator('$rootScope', [
'$delegate', function($delegate) {
$delegate.safeApply = function(fn) {
var phase = $delegate.$$phase;
if (phase === "$apply" || phase === "$digest") {
if (fn && typeof fn === 'function') {
fn();
}
} else {
$delegate.$apply(fn);
}
};
return $delegate;
}
]);
}
]).service('context', function(){
var a = App.Factory();
a.addEvent('aImpl');
a.addEvent('aImpl');
return{
subscribe: function(handler, func){
return a.subscribe(handler, func);
},
unsubscribe: function(handler, token){
return a.unsubscribe(handler, token);
},
act: function(actor, result){
a.act(actor, result);
}
};
}).controller('Ctrl', ['$scope', '$rootScope', 'context', function SecondCtrl($scope, $rootScope, context) {
$scope.data1 = 2;
var sub1 = context.subscribe('aImpl', function(result){
$rootScope.safeApply(function(){
$scope.data1 = result;
});
});
$scope.data2 = 2;
var sub2 = context.subscribe('bImpl', function(result){
$rootScope.safeApply(function(){
$scope.data2 = result;
});
});
$scope.cl = function(){
context.act('aImpl', $scope.data1);
};
$scope.cl2 = function(){
context.act('aImpl', $scope.data2 * 2);
};
$scope.cl3 = function(){
context.unsubscribe('bImpl', sub2);
};
}]);