angular - 是否可以从入口组件访问服务

标签 angular

我正在使用一个入口组件,该组件需要访问不是在根级别而是在功能模块级别提供的服务。该服务当前在根组件中提供。入口组件无法在入口组件构造函数中通过 DI 访问该服务实例。我也曾尝试通过模块中的 providers 提供服务,但也没有成功。当服务不在根注入(inject)器级别时,是否有可能以某种方式访问​​入口组件中的服务实例?

例如功能模块:

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 { }

当前在 Feature_Root_Component 中提供了一项服务。即:

@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) {}
}

现在,当我尝试在入口组件构造函数中访问此服务时,我得到一个 NullInjectorError。作为解决方法,我改为将服务作为输入参数传递给入口组件并以这种方式访问​​它。但是,这非常麻烦并且看起来不是一个好的实现,因为入口组件中的任何嵌套组件也必须将服务传递给它们。

最佳答案

显然入口组件现在已被弃用,但由于我仍在使用 Angular 7,我想我可以回答这个问题。

Angular 对入口组件的定义是 a bit broader than this ,但在您的情况下,假设入口组件只是您“通过 JavaScript”动态创建的组件(而不是在某些组件的模板中静态使用它)。

在 Angular 中,您可以使用组件工厂来动态创建组件。这是一个基本示例:

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
}

请注意,factory.create() 唯一需要的参数是 Injector 的一个实例。注入(inject)器定义了组件的依赖注入(inject)范围,换句话说 - 组件可以访问哪些服务(和其他依赖项)。

在上面的示例中,我使用了与创建组件相同的注入(inject)器。因此,创建组件可用(由其提供)的任何服务在 MyEntryComponent 中也可用。我也可以在这里自由使用不同的注入(inject)器 - 例如,我可以使用 Root Injector(在这种情况下,MyEntryComponent 将只能访问 providedIn: 'root' 中的服务)。

现在,一个典型的 UI 对话框库将向您隐藏所有这些。不幸的是,如果他们没有为您提供一种提供 Injector 实例的方法,那么您可能就不走运了。例如。 Angular 的 Material Dialog 允许这样做,但是快速查看 UI Dialog 库的文档表明没有这样的功能(尽管似乎有计划包含它,但不确定是否已实现:https://github.com/NG-ZORRO/ng-zorro-antd/issues/4710)。

关于angular - 是否可以从入口组件访问服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57950456/

相关文章:

javascript - 使用 Angular 2 实现选项卡

angular - typescript ,固定。类型 'string' 不可分配给类型 'number'

angular - Typescript导入别名+桶文件

asp.net - Angular 5/ASP.NET - “No ResourceLoader implementation has been provided. Can' t 读取 URL”

javascript - angular2 ngIf 真或假条件

angular - 在 AngularJS 2 中,当使用路由配置调用子组件时,管理父组件和子组件之间的输入/输出属性的方法是什么

Angular 6 - ngModel 的值仅在单击某处时出现

angular - 刷新 Angular 应用程序的浏览器时,i18n 文件夹问题

angular - 从 Angular 2 上的查询参数中预填充输入文本框

angular - Angular 2+的 masonry 替代品