简体   繁体   中英

how to call angular factory method from module setup?

I have a module App and factory i18n , what is the best way to call i18n.load method form App (config? run? etc?)

angular
  .module('App', [
    'ngRoute',
    'service.i18ndb'
  ])
  .config(function ($routeProvider) {

    //want to i18n.load() here somehow

    $routeProvider
      .when('/signin', {
        templateUrl: '../views/sign-in.html',
        controller: 'SigninCtrl'
      })
      .when('/mix', {
        templateUrl: '../views/mix.html',
        controller: 'MixCreateCtrl'
      })
      .otherwise({
        redirectTo: '/signin'
      });
  });


angular.module('App')
  .factory('service.i18ndb', function() {
    return {
      load: function() { console.log("Busy"); }
    }
  }
);

The problem you will always have if you use .run is having to deal with a page that has no i18n loaded. This means you will need to have a way to deal with your view when their is no i18n loaded. You can either hide it or the text will flash with the wrong values at first.

However, AngularJS gives you a wonderful feature to make sure it is loaded before your view is loaded: the resolver!

Here is how to do it.

var i18nResolver = function(service.i18ndb) {
  return service.i18ndb.promise;
};

$routeProvider
  .when('/signin' {
    templateUrl: '../views/sign-in.html',
    controller: 'SigninCtrl',
    resolve: {
      i18n: i18nResolver
    }
  });

You can fix this code to use the correct promise of your HTTP request or whatever service you are using.

One of the benefits of using this way is you can have a different labels for a different page for your i18n and use the i18n service to recover them no matter where you are.

You are defining your app module twice. One you create your factory, it can be injected to the controller and used there. You could try something like this:

  angular.module('App', ['ngRoute','service.i18ndb'])
  .factory('service.i18ndb', function() {
    return {
      load: function() { console.log("Busy"); }
    }
  })
  .config(function ($routeProvider) {

    //want to i18n.load() here somehow

    $routeProvider
      .when('/signin', {
        templateUrl: '../views/sign-in.html',
        controller: 'SigninCtrl'
      })
      .when('/mix', {
        templateUrl: '../views/mix.html',
        controller: 'MixCreateCtrl'
      })
      .otherwise({
        redirectTo: '/signin'
      });
  })
  .controller('SigninCtrl', function($scope, service.i18ndb) {
      // Call your factory function here
      service.i18ndb.load();
      // If the function returns a value you could assign it to a scope
      // variable so it can be used in your template 'sign-in.html'
      $scope.your_variable = service.i18ndb.load();
  });
angular
  .module('App', [
    'ngRoute'
  ])
  .config(function ($routeProvider) {

    //want to i18n.load() here somehow

    $routeProvider
      .when('/signin', {
        templateUrl: '../views/sign-in.html',
        controller: 'SigninCtrl'
      })
      .when('/mix', {
        templateUrl: '../views/mix.html',
        controller: 'MixCreateCtrl'
      })
      .otherwise({
        redirectTo: '/signin'
      });
  })
    .run(['i18ndb', function(i18ndb) {
      i18ndb.load();
    }])

    .factory('i18ndb', function() {
      return {
        load : function() {console.log('test')}
      };
    });
);

You were requiring a module which has not been defined (as far as I can tell). The factory you were adding was on the 'App' module not the 'service.i18ndb'.

You then need to dependency inject the i18ndb factory in to the run method to call it from there (presuming that you want to call that function to bootstrap your app).

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