服务在APP_INITIALIZER之后实例化两次 [英] Service instantiated twice after APP_INITIALIZER

查看:100
本文介绍了服务在APP_INITIALIZER之后实例化两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题是:我需要进行http调用并存储生成动态路由所需的对象.因此,我正在利用APP_INITIALIZER.

Problem is: I need to make an http call and store an object that is needed for generate dynamic routes. So, I was taking advantage of the APP_INITIALIZER.

// app.module.ts
import { ApplicationService } from './application.service';


providers: [
  ApplicationService,
  { 
  provide: APP_INITIALIZER, useFactory: appServiceFactory, deps: 
  [Injector, ApplicationService], multi: true 
  },
],

function appServiceFactory(injector: Injector, appService: ApplicationService): Function {
  return () => {
    return appService.loadApplication().then((app: Application) => {
      /custom logic
      });
    });
  };
}


// application.service.ts
@Injectable({
  providedIn: 'root'
})

// navigation.component.ts
import { ApplicationService } from './application.service';

export class NavigationComponent implements OnInit {

    constructor(private _applicationService: ApplicationService) {
  }
}    

但是在navigation.component内部,applicationservice再次被初始化.我敢肯定,因为如果我记录或放置调试器语句,则该服务的Construct()方法将被调用两次.

But inside navigation.component, applicationservice is initialized again. I'm sure of that because if I log or put a debugger statement, the construct() method of the service is called twice.

为什么要重新实例化带有 providedIn:root 的服务为单例?

Why even if the Service is declared as singleton with the providedIn: root is being reinstantiated?

推荐答案

原因是,一旦在 APP_INITIALIZER 工厂的依赖项中包含 Router 依赖项( https://github.com/angular/angular/blob/4c2ce4e8ba4c5ac5ce8754d67bc6603eaad4564a/packages/router/src/router_module.ts#L61-L64 ).

The reason for this is that once you include Router in dependencies to your APP_INITIALIZER factory you get circular dependency (https://github.com/angular/angular/blob/4c2ce4e8ba4c5ac5ce8754d67bc6603eaad4564a/packages/router/src/router_module.ts#L61-L64).

ApplicationService
       |
    TestService
       |
     Router
       |
  ApplicationRef
       |
ApplicationInitStatus
       |
 APP_INITIALIZER
       |
ApplicationService

要解决此问题,您可以懒惰地获得路由器:

To solve this you can get Router lazily:

export class TestService {

  get router() {
    return this.injector.get(Router)
  }

  constructor(private _http: HttpClient, private injector: Injector ) {
  }
}

分叉的Stackblitz

Forked Stackblitz

这篇关于服务在APP_INITIALIZER之后实例化两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆