code: function (callback) {
              return function (e) {
                var newValue = session.getValue();
  
                if (ngModel && newValue !== ngModel.$viewValue &&
                    // HACK make sure to only trigger the apply outside of the
                    // digest loop 'cause ACE is actually using this callback
                    // for any text transformation !
                    !scope.$$phase && !scope.$root.$$phase) {
                  scope.$evalAsync(function () {
                    ngModel.$setViewValue(newValue);
                  });
                }
  
                executeUserCallback(callback, e, acee);
              };
            }
docs: Creates a change listener which propagates the change event
  and the editor session to the callback from the user option
  onChange. It might be exchanged during runtime, if this
  happens the old listener will be unbound.
  
  @param callback callback function defined in the user options
  @see onChangeListener