简体   繁体   中英

Defining global functions and properties accessible by AngularJS factory and controllers

I'm working on an AngularJS app. When an error is thrown, I want to do some custom handling of the error. To do that, I've done the following:

var myApp = angular.module('myApp', []);
myApp.factory('$exceptionHandler', function($rootScope) {
  return function(exception, cause) {
    try {
      console.log('Unhandled error happening in version ' + $rootScope.APP_VERSION);
      console.log('Error happened at ' + $rootScope.getFormattedDateTime());
    } catch (uex1) {
      console.log('Unable to log unhandled exception.');
    }
  };
});

myApp.run(function ($rootScope) {
  $rootScope.APP_VERSION = '1.0';
  $rootScope.getFormattedDateTime = function() {
    return '--';
  };
});

When I run this code, I get this error . I guess I can't add $rootScope to factory declarations. If that's the case, how do I define globally accessible functions and variables so that I can access them in my controllers as well as from this factory?

Thank you so much for any assistance you can provide.

You cant inject $routeScope into a factory , and this is not a good idea However

The best you can do is to define a new factory , and define your property into that factoy like this :

   app.factory('getAppInfoFactory',function(){
    return{
    getAppVersion:function(){
       return APP_VERSION = '1.0';
      },
    getFormattedDateTime : function() {
         return '--';
     }
 });

And then you can simply use this factory whenever/whereever you want , like this :

  myApp.factory('$exceptionHandler', function(getAppInfoFactory) {
    return function(exception, cause) {
      try {
        console.log('Unhandled error happening in version ' + getAppInfoFactory.getAppVersion());
        console.log('Error happened at ' + getAppInfoFactory.getAppInfoFactory());
      } catch (uex1) {
        console.log('Unable to log unhandled exception.');
      }
    };
  });

This would definitely be the cleanest approach. You could easily swap out the $filter with a service that does the same thing, however, I find this approach cleaner as it can be passed arbitrary dates.

Here is a plunkr that demonstrates the code below (Plunkr also includes some fancy ways of logging errors): http://plnkr.co/edit/iPMFTJ

angular
  .module('app', [])
  .constant({ APP_VERSION: '1.0' })
  .config(function ($provide) {
    function exceptionHandler($delegate, $filter, $log, APP_VERSION) {
      return function handleException(exception, cause) {
        var formatDateTime = $filter('formatDateTime');
        try {
          $log.error('Unhandled error happening in version ' + APP_VERSION);
          $log.warn('Error happened at ' + formatDateTime(new Date()));
        } catch (uex1) {
          $log.info('Unable to log unhandled exception.');
        }
        // Include the line below if you want angular's default exception
        // handler to run as well
        // $delegate(exception, cause);

      };
    }
    $provide.decorator("$exceptionHandler", exceptionHandler);
  });

angular
  .module('app')
  .filter('formatDateTime', function formatDateTimeFilter($filter) {
    return function formatDateTime(date) {
      return $filter('date')(date, 'shortDate');
    };
  })
  .controller('ErrorCtrl', function () {
    throw new Error('testError');
  });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM