AngularJS UI Router using resolved dependency in factory / service

后端 未结 3 1303
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-02-09 15:04

I have a UI Router defined something like this (trimmed for simplicity):

    $stateProvider
        .state(\'someState\', {
            resolve: {
                       


        
相关标签:
3条回答
  • 2021-02-09 15:19

    Do resolves only work on controllers?

    Yes, resolves only work on controllers.

    And if that is the case, how can I use a resolve inside a factory / service?

    Remember that factories and services return singleton objects, i.e. the first time a factory is injected into a controller, it runs any instantiation code you provide and creates an object, and then any subsequent times that factory is instantiated, that same object is returned.

    In other words:

    angular.module('someModule')
    .factory( 'SomeFactory' , function () {
      // this code only runs once
      object = {}
      object.now = Date.now();
      return object
    );
    

    SomeFactory.now will be the current time the first time the factory is injected into a controller, but it not update on subsequent usage.

    As such, the concept of resolve for a factory doesn't really make sense. If you want to have a service that does something dynamically (which is obviously very common), you need to put the logic inside functions on the singleton.

    For example, in the code sample you gave, your factory depended on a model. One approach would be to inject the model into the controller using the resolve method you've already got set up, then expose a method on the singleton that accepts a model and does what you need to do, like so:

    angular.module('someModule')
    .factory( 'SomeFactory', function () {
      return {
        doSomethingWithModel: function (model) {
          $http.post('wherever', model);
      }
    });
    .controller('SomeController', function (SomeFactory, model) {
      SomeFactory.doSomethingWithModel(model);
    });
    

    Alternatively, if you don't need the resolved value in the controller at all, don't put it directly in a resolve, instead put the resolve logic into a method on the service's singleton and call that method inside the resolve, passing the result to the controller.

    It's hard to be more detailed with abstract conversation, so if you need further pointers then provide a specific use-case.

    0 讨论(0)
  • 2021-02-09 15:29

    You should review the angular docs on dependency injection:

    • Components such as services, directives, filters, and animations are defined by an injectable factory method or constructor function. These components can be injected with "service" and "value" components as dependencies.
    • Controllers are defined by a constructor function, which can be injected with any of the "service" and "value" components as dependencies, but they can also be provided with special dependencies. See Controllers below for a list of these special dependencies.
    • The run method accepts a function, which can be injected with "service", "value" and "constant" components as dependencies. Note that you cannot inject "providers" into run blocks.
    • The config method accepts a function, which can be injected with "provider" and "constant" components as dependencies. Note that you cannot inject "service" or "value" components into configuration.

    So each type of angular component has its own list of acceptable components to inject. Since services are singletons, it really wouldn't make any sense to inject a value as part of a resolve. If you had two separate places on your page that used a service with different resolves, the outcome would be indeterminate. It would make no more sense than injecting $scope into your service. It makes sense for controllers because the controller is responsible for the same area of the page that is being resolved.

    If your someService needs to use the data in model, it should have a function that takes the data as a parameter and your controller should pass it.

    0 讨论(0)
  • 2021-02-09 15:37

    You cannot use the resolved values in services or factories, only in the controller that belongs to the same state as the resolved values. Services and factories are singletons and controllers are newly instantiated for (in this case) a state or anywhere else where ng-controller is used.

    The instantiation happens with the $controller service that is capable of injecting objects that belong only to that controller. Services and factories do not have this capability.

    0 讨论(0)
提交回复
热议问题