programing

기능 모듈 계층 구조 내에서 .forRoot ()를 사용하는 방법

goodcopy 2021. 1. 19. 08:03
반응형

기능 모듈 계층 구조 내에서 .forRoot ()를 사용하는 방법


누구든지 .forRoot () 호출을 사용하여 여러 중첩 기능 모듈 계층 구조를 구성하는 방법을 설명해 주시겠습니까?

예를 들어 다음과 같은 모듈이있는 경우 :

- MainModule
- SharedModule
- FeatureModuleA
    - FeatureModuleA1
    - FeatureModuleA2
- FeatureModuleB

모든 기능 모듈에는 .forRoot () 정적 함수가 있습니다.

.forRoot () 함수를 "전송"하여 FeatureModuleA 를 어떻게 정의해야 합니까?

@NgModule({ 
  imports: [
    //- I can use .forRoot() calls here but this module not the root module
    //- I don't need to import sub-modules here, FeatureA only a wrapper
    //FeatureModuleA1.forRoot(), //WRONG!
    //FeatureModuleA2.forRoot(), //WRONG!
  ],
  exports: [
    //I cannot use .forRoot() calls here
    FeatureModuleA1, 
    FeatureModuleA2 
  ]
})
class FeatureModuleA {
  static forRoot(): ModuleWithProviders {
    return {
      //At this point I can set any other class than FeatureModuleA for root
      //So lets create a FeatureRootModuleA class: see below!
      ngModule: FeatureModuleA //should be: FeatureRootModuleA 
    };
  }
}

루트 사용을위한 다른 클래스를 만든 다음 FeatureModuleA의 forRoot () 함수 내에서 설정할 수 있습니다.

@NgModule({
  imports: [
    //Still don't need any sub module within this feature module
  ]
  exports: [
    //Still cannot use .forRoot() calls but still need to export them for root module too:
    FeatureModuleA1, 
    FeatureModuleA2 
  ]
})
class FeatureRootModuleA { }

하지만이 특별한 ModuleClass 내에서 .forRoot () 호출을 어떻게 "전송"할 수 있습니까?

내가 볼 수 있듯이 모든 하위 모듈을 루트 MainModule로 직접 가져오고 각각에 대해 .forRoot ()를 호출해야합니다.

@NgModule({
  imports: [
    FeatureModuleA1.forRoot(),
    FeatureModuleA2.forRoot(),
    FeatureModuleA.forRoot(),
    SharedModule.forRoot()
  ]
})
class MainModule { }

내가 맞아? 답변하기 전에 https://github.com/angular/material2/blob/master/src/lib/module.ts 파일을 살펴보십시오.

내가 아는 것처럼이 저장소는 공식 앵귤러 팀에서 관리합니다. 따라서 특수 MaterialRootModule 모듈 내에서 모든 .forRoot () 호출을 가져 와서 위의 문제를 해결합니다. 내 루트 모듈에 어떻게 적용 될지 정말 이해가 안 되나요? 여기서 루트.forRoot는 실제로 무엇을 의미합니까? 실제 웹 프로젝트가 아니라 패키지와 관련이 있습니까?


일반적으로 forRoot응용 프로그램 / 단일 서비스를 추가하는 데 사용됩니다.

@NgModule({
  providers: [ /* DONT ADD HERE */ ]
})
class SharedModule {
  static forRoot() {
    return {
      ngModule: SharedModule,
      providers: [ AuthService ]
    }
  }
}

추론은 당신이를 추가하는 경우이다 AuthService받는 providers@NgModule하나 이상 생성하는 당신이 가져올 경우, 그것은 가능성이 SharedModule다른 모듈에.

I'm not 100% clear on whether the service would be created when the SharedModule is imported into an eagerly loaded module, but the explanation that the docs mentioned was in regards to lazily loaded modules. When you lazily load a module, all the providers will get created.

For this reason, we add a (by convention) forRoot method to signify that the method should only be called for the root (app) module, while for other module it should just be imported normally

@NgModule({
  imports: [SharedModule]
})
class FeatureModule {}

@NgModule({
  imports: [SharedModule.forRoot()]
})
class AppModule {}

As forRoot intended only to provide singleton services, you can "re-provide" them explicitly in SharedModule:

@NgModule({})
class SharedModule {
  static forRoot() {
    return {
      ngModule: SharedModule,
      providers: [
        AuthService,
        FeatureModuleA.forRoot().providers,
        FeatureModuleB.forRoot().providers,
      ],
    }
  }
}

This way all the services will be provided by the SharedModule itself (not by respective sub-module) but it seems that it doesn't matter. Maybe someone can argue though...

Note, that FeatureModuleA can also "re-provide" singleton services from its sub-modules it similar manner.


As mentioned above, lazy loaded modules are important to consider because a shared service could be used in a lazy loaded module, but if that service was already used and instantiated by another module, then there will be two instances hence the need for the singleton pattern. An AuthService is a great example here - you don't want to have one instance of the service with an unauthenticated user while another has "the same" user authenticated.

New to Angular 6 there is a new way to register a provider as a singleton. Inside the @Injectable() decorator for a service, use the providedIn attribute. Set its value to 'root'. Then you won't need to add it to the providers list of the root module, or in this case you could also set it to your SharedModule like this:

@Injectable({
  providedIn: SharedModule // or 'root' for singleton
})
export class AuthService {
...

ReferenceURL : https://stackoverflow.com/questions/39653072/how-to-use-forroot-within-feature-modules-hierarchy

반응형