// None angular part
(function(){
  function changeColor(){
    var colors = ['orange', 'gray', 'yellow'];
    $('#nonAngular').css('background-color', colors[Math.round(Math.random()*2)]);
  }
  
  $(document).on('ready', function(){
    
    window.appMediator.subscribe('angularChannel', changeColor);
    $('#nonAngular').on('click', function(){
      window.appMediator.publish('externalChannel');
    });
  });
})();

// angular part
(function(){
  var app = angular.module('app', []);

    app.directive('someDirective', ['$log', 'mediator', function($log, mediator){
      return {
        restrict: 'E',
        controllerAs: 'someDirective',
        template: '<button ng-click="someDirective.clickMe()">Click Some Directive</button>',
        controller: function($scope, $element){
          function changeColor(){
            var colors = ['orange', 'gray', 'yellow'];
            $element.find('button').css('background-color', colors[Math.round(Math.random()*2)]);
          }
          
          var vm = this;
          
          vm.clickMe = function clickMe(){
            mediator.publish('angularChannel');
          };
          
          mediator.subscribe('externalChannel', changeColor);
        },
        link: function(scope, element, attr, ctrl){
          
        }
      };
    }]);
    
    app.service('mediator', [function(){
      window.appMediator = new Mediator(); // keep in global for external app
      return window.appMediator; // return for ng use
    }])
    angular.bootstrap($('#myApp')[0], ['app']);
    
    
})();

.grid {
  width: 600px;
}

.hovered{
  outline: red 2px solid;
}
<!DOCTYPE html>
<html>

  <head>
    <script data-require="jquery@*" data-semver="2.2.0" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
    <script src="mediator.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-touch.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-animate.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/csv.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/pdfmake.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/vfs_fonts.js"></script>
    <script src="http://ui-grid.info/release/ui-grid.js"></script>
    <link rel="stylesheet" href="http://ui-grid.info/release/ui-grid.css" type="text/css" />
    <link rel="stylesheet" href="main.css" type="text/css" />
  </head>

  <body>
    <button id="nonAngular">Non Angular Click</button>
    <div id="myApp">
      <some-directive></some-directive>
    </div>
    <script src="app.js"></script>
  </body>

</html>
!function(a,b){"use strict";"function"==typeof define&&define.amd?define("mediator-js",[],function(){return a.Mediator=b(),a.Mediator}):"undefined"!=typeof exports?exports.Mediator=b():a.Mediator=b()}(this,function(){"use strict";function a(){var a=function(){return(0|65536*(1+Math.random())).toString(16).substring(1)};return a()+a()+"-"+a()+"-"+a()+"-"+a()+"-"+a()+a()+a()}function b(c,d,e){return this instanceof b?(this.id=a(),this.fn=c,this.options=d,this.context=e,this.channel=null,void 0):new b(c,d,e)}function c(a,b){return this instanceof c?(this.namespace=a||"",this._subscribers=[],this._channels={},this._parent=b,this.stopped=!1,void 0):new c(a)}function d(){return this instanceof d?(this._channels=new c(""),void 0):new d}return b.prototype={update:function(a){a&&(this.fn=a.fn||this.fn,this.context=a.context||this.context,this.options=a.options||this.options,this.channel&&this.options&&void 0!==this.options.priority&&this.channel.setPriority(this.id,this.options.priority))}},c.prototype={addSubscriber:function(a,c,d){var e=new b(a,c,d);return c&&void 0!==c.priority?(c.priority=c.priority>>0,c.priority<0&&(c.priority=0),c.priority>=this._subscribers.length&&(c.priority=this._subscribers.length-1),this._subscribers.splice(c.priority,0,e)):this._subscribers.push(e),e.channel=this,e},stopPropagation:function(){this.stopped=!0},getSubscriber:function(a){var b=0,c=this._subscribers.length;for(c;c>b;b++)if(this._subscribers[b].id===a||this._subscribers[b].fn===a)return this._subscribers[b]},setPriority:function(a,b){var e,f,g,h,c=0,d=0;for(d=0,h=this._subscribers.length;h>d&&this._subscribers[d].id!==a&&this._subscribers[d].fn!==a;d++)c++;e=this._subscribers[c],f=this._subscribers.slice(0,c),g=this._subscribers.slice(c+1),this._subscribers=f.concat(g),this._subscribers.splice(b,0,e)},addChannel:function(a){this._channels[a]=new c((this.namespace?this.namespace+":":"")+a,this)},hasChannel:function(a){return this._channels.hasOwnProperty(a)},returnChannel:function(a){return this._channels[a]},removeSubscriber:function(a){var b=this._subscribers.length-1;if(!a)return this._subscribers=[],void 0;for(b;b>=0;b--)(this._subscribers[b].fn===a||this._subscribers[b].id===a)&&(this._subscribers[b].channel=null,this._subscribers.splice(b,1))},publish:function(a){var e,g,h,b=0,c=this._subscribers.length,d=!1;for(c;c>b;b++)d=!1,e=this._subscribers[b],this.stopped||(g=this._subscribers.length,void 0!==e.options&&"function"==typeof e.options.predicate?e.options.predicate.apply(e.context,a)&&(d=!0):d=!0),d&&(e.options&&void 0!==e.options.calls&&(e.options.calls--,e.options.calls<1&&this.removeSubscriber(e.id)),e.fn.apply(e.context,a),h=this._subscribers.length,c=h,h===g-1&&b--);this._parent&&this._parent.publish(a),this.stopped=!1}},d.prototype={getChannel:function(a,b){var c=this._channels,d=a.split(":"),e=0,f=d.length;if(""===a)return c;if(d.length>0)for(f;f>e;e++){if(!c.hasChannel(d[e])){if(b)break;c.addChannel(d[e])}c=c.returnChannel(d[e])}return c},subscribe:function(a,b,c,d){var e=this.getChannel(a||"",!1);return c=c||{},d=d||{},e.addSubscriber(b,c,d)},once:function(a,b,c,d){return c=c||{},c.calls=1,this.subscribe(a,b,c,d)},getSubscriber:function(a,b){var c=this.getChannel(b||"",!0);return c.namespace!==b?null:c.getSubscriber(a)},remove:function(a,b){var c=this.getChannel(a||"",!0);return c.namespace!==a?!1:(c.removeSubscriber(b),void 0)},publish:function(a){var b=this.getChannel(a||"",!0);if(b.namespace!==a)return null;var c=Array.prototype.slice.call(arguments,1);c.push(b),b.publish(c)}},d.prototype.on=d.prototype.subscribe,d.prototype.bind=d.prototype.subscribe,d.prototype.emit=d.prototype.publish,d.prototype.trigger=d.prototype.publish,d.prototype.off=d.prototype.remove,d.Channel=c,d.Subscriber=b,d.version="0.9.8",d});