code: function(name, listener) {
          var namedListeners = this.$$listeners[name];
          if (!namedListeners) {
            this.$$listeners[name] = namedListeners = [];
          }
          namedListeners.push(listener);
  
          var current = this;
          do {
            if (!current.$$listenerCount[name]) {
              current.$$listenerCount[name] = 0;
            }
            current.$$listenerCount[name]++;
          } while ((current = current.$parent));
  
          var self = this;
          return function() {
            namedListeners[indexOf(namedListeners, listener)] = null;
            decrementListenerCount(self, 1, name);
          };
        }
docs: @ngdoc method
  @name $rootScope.Scope#$on
  @kind function
  
  @description
  Listens on events of a given type. See {@link ng.$rootScope.Scope#$emit $emit} for
  discussion of event life cycle.
  
  The event listener function format is: `function(event, args...)`. The `event` object
  passed into the listener has the following attributes:
  
  - `targetScope` - `{Scope}`: the scope on which the event was `$emit`-ed or
  `$broadcast`-ed.
  - `currentScope` - `{Scope}`: the scope that is currently handling the event. Once the
  event propagates through the scope hierarchy, this property is set to null.
  - `name` - `{string}`: name of the event.
  - `stopPropagation` - `{function=}`: calling `stopPropagation` function will cancel
  further event propagation (available only for events that were `$emit`-ed).
  - `preventDefault` - `{function}`: calling `preventDefault` sets `defaultPrevented` flag
  to true.
  - `defaultPrevented` - `{boolean}`: true if `preventDefault` was called.
  
  @param {string} name Event name to listen on.
  @param {function(event, ...args)} listener Function to call when the event is emitted.
  @returns {function()} Returns a deregistration function for this listener.