Angular Service SubPub Mixin

by mslocum

HTML

<div ng-controller="Ctrl">
    <p>Count up: {{ iCount }}</p>
    <p>Count down: {{ iCountDown }}</p>
    <button ng-click="doStuff()">Do Stuff</button>
</div>

JavaScript

// Start Angular stuff
var app = angular.module('myApp', []);

app.service('Notify', ["$q", function($q) {
    var aNotices = [];

    this.onChange = function(fCallback, fServiceChange) {
        aNotices.push({
            obj: this, 
            callback: fCallback,
            func: fServiceChange
        });
    };
    
    this.notify = function(mValue, fServiceChange) {
        var $this = this;
        angular.forEach(aNotices, function(oNotice) {
            if (oNotice.obj === $this) {
                // either the onChange wants all service changes OR
                // if there is a specific function on the service, then that needs to match
                if (!oNotice.func || oNotice.func === fServiceChange) {
                    oNotice.callback(mValue);
                }
            }
        });
    };
}]);


/** TESTING SERVICES **/
app.service('Data', ["$q", "Notify", function($q, Notify){
    // Mixin Notify
    angular.extend(this, Notify);
    
    var iCounter = 0;
    
    this.increment = function(){
        iCounter++;
        // notify interested parties that the get() method now has new data
        this.notify(iCounter, this.get);
    };
    
    this.get = function() {
        var oDeferred = $q.defer();
        oDeferred.resolve(iCounter);
        return oDeferred.promise;
    };
}]);

app.service('Data2', ["$q", "Notify", function($q, Notify){
    // Mixin Notify
    angular.extend(this, Notify);
    
    var iCounter = 100;
    
    this.decrement = function(){
        iCounter--;
        // notify interested parties
        this.notify(iCounter, this.get);
    };
    
    this.get = function() {
        var oDeferred = $q.defer();
        oDeferred.resolve(iCounter);
        return oDeferred.promise;
    };
}]);


/**** TESTING CONTROLLER ****/
function Ctrl($scope, Data, Data2)
{
    $scope.iCount;
    $scope.iCountDown;
    
    //console.log(Data == Data2);
    
    Data.get().then(function(iCount) {
        $scope.iCount =...