简体   繁体   中英

Is it possible to access Service from an entry component

I'm using an entry component that needs access to a service that is provided not at the root level, but at a feature module level. The service is currently provided in a root component. The entry component cannot access this service instance via DI in the entry component constructor. I have also tried providing the service via providers in the module, but also no luck. Is it possible to somehow gain access to a service instance in an entry component when the service is not at the root injector level?

Eg a feature module:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Routing_Module } from './routing.module';

// Components
import { Feature_Root_Component } from './feature/feature.component';
import { Management_Component } from './feature/management.component';


@NgModule({
  declarations: [
    Feature_Root_Component,
  ],
  entryComponents: [
    Management_Component,
  ],
  imports: [
    CommonModule,
  ],
})
export class Event_Module { }

There is a service currently being provided in Feature_Root_Component . Ie:

@Component({
  selector: 'feature-root',
  templateUrl: './feature.component.html',
  styleUrls: ['./feature.component.scss'],
  providers: [Feature_Service],
})
export class Feature_Root_Component implements OnInit, OnDestroy {
  constructor(private feature_service: Feature_Service) {}
}

Now when I try to access this service in the entry component constructor, I get a NullInjectorError. As a workaround, I instead pass the service as an input parameter to the entry component and access it that way. Though, this is very cumbersome and does not seem like a good implementation, as any nested components in the entry component must also have the service passed to them.

Apparently Entry Components are now deprecated, but since I am still on Angular 7 I think I can answer this.

Angular's definition of an Entry Component is a bit broader than this , but in your case let's say that an Entry Component is simply one that you create dynamically "via JavaScript" (as opposed to using statically it in some component's template).

In Angular you would use a Component Factory to create a component dynamically. Here's a basic example:

constructor(
  private resolver: ComponentFactoryResolver,
  private injector: Injector,
) {}

ngOnInit() {
  // First you obtain an instance of the Component Factory for your entry component
  const factory = this.resolver.resolveComponentFactory(MyEntryComponent);

  // You then use that factory to instantiate the component
  const layersComponent = factory.create(this.injector) as ComponentRef<MyEntryComponent>;

  // After this you can insert the component into the DOM, or do whatever with it
}

Notice here that the only required parameter to factory.create() is an instance of an Injector. An Injector is what defines the Dependency Injection scope of a Component, in other words - which Services (and other dependencies) the component will have access to.

In the above example I am using the same Injector, which the creating component uses. So any Services available (provided by) the creating component would also be available in MyEntryComponent. I am free to use a different Injector here too - I could use the Root Injector, for example (in which case MyEntryComponent would only have access to Services, which are providedIn: 'root' ).

Now, a typical UI Dialog library will hide all of this away from you. Unfortunately, if they haven't exposed a way for you to provide an Injector instance, then you are likely out of luck. Eg Angular's Material Dialog allows this, but a quick look at the docs of your UI Dialog lib suggests that there is no such functionality (although it seems that there were plans to include it, not sure if implemented: https://github.com/NG-ZORRO/ng-zorro-antd/issues/4710 ).

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