我正在try 为库模块创建一个提供程序,当添加该提供程序时会触发我的工厂提供程序.然而,当我这样做时,提供程序从来没有执行console.log,所以我知道它没有运行.

下面是我try 实例化的示例服务:

@Injectable()
export class ExampleService {
  addOptions(...options: any[]) {
    // Set options
  }
}

在创建模块时,我希望创建服务并向其添加一些默认选项,因此我创建了一个工厂提供程序,因为我不想在组件级别添加它,或者为ExampleService的每个实例添加它.这一模块只有一次机会.

@NgModule({
  declarations: [ExampleComponent],
  exports: [ExampleComponent],
  providers: [
    {
      provide: ExampleService,
      multi: false,
      useFactory: () => {
        console.log('Creating Example Service...');
        const service = new ExampleService();
        service.addOptions('one', 'two', 'three');
        return service;
      }
    }
  ],
})
export class LibraryModule {}

我也有一个组件,我也想将服务注入其中,但不与模块中的组件共享同一个实例,所以我这样做了:

@Component({
  providers: [ExampleService]
})
export class ExampleComponent {
  constructor(private example: ExampleService) {}
}

当我公司的一个团队使用我们的库时,他们会像这样导入它,并且选项会从LibraryModule自动设置.

@NgModule({
  imports: [LibraryModule]
})
export class App {}

目前,组件中的一个按预期创建,但模块中的一个没有运行工厂,因为我看不到console.log的输出.我需要做什么来解决这个问题?或者,这不是正确的方法吗?


Note:我正在用故事书测试这个,不确定这是否有区别.

看起来像这样:

@Component({
  standalone: true,
  imports: [LibraryModule]
})
export class StorybookExample {
  constructor(private example: ExampleService) {}
}

export default {
  title: 'Test',
  component: StorybookExample,
} as Meta<StorybookExample>;

推荐答案

Angular在使用服务时实例化服务,即当它创建了注入该服务的东西时.这就是为什么仅仅指定工厂是不够的——工厂只有在服务在某个地方使用时才被调用.

你可以做的是将服务注入到模块的构造函数中:

@NgModule({
  declarations: [ExampleComponent],
  exports: [ExampleComponent],
  providers: [ExampleService],
})
export class LibraryModule {
  constructor(exampleService: ExampleService) {
    service.addOptions('one', 'two', 'three');
  }
}

请记住,导入此模块并不强制创建新的实例—如果服务被提供并注入到其他地方,可能已经有一个实例将被传递给模块构造函数.

由于延迟加载的模块创建了注入器,所以如果这个模块作为延迟加载的模块的一部分导入,则会为延迟加载的模块的作用域创建一个新实例.

Playgroud

如果这看起来很乱,那就是.不久前,Angular引入了独立API,这使得无需使用NgModule就可以拥有一个应用程序.并且有一个特殊的DI令牌,它可以用于运行初始化逻辑:

  providers: [
    {
      provide: ENVIRONMENT_INITIALIZER,
      multi: true,
      useValue: () => {
        inject(ExampleService).addOptions('one', 'two', 'three');
      }
    }
  ]

这可以为bootstrapApplication或为路由配置指定.

Javascript相关问答推荐

是什么原因导致此Angular 16电影应用程序中因类型错误而不存在属性?

是什么原因导致此Angular 16应用程序中类型错误时属性结果不存在?

函数返回与输入对象具有相同键的对象

手机上的渲染错误文本必须在文本组件中渲染,但在浏览器上没有问题<><>

为什么Mutations 观察器用微任务队列而不是macrotask队列处理?

如何使onPaste事件与可拖动的HTML元素一起工作?

我创建了一个创建对象的函数,我希望从该函数创建的对象具有唯一的键.我怎么能做到这一点?

如何从HTML对话框中检索单选项组的值?

JavaScript是否有多个`unfined`?

在验证和提交表单后使用useNavigate()进行react 重定向,使用带有加载器和操作的路由

为什么NULL不能在构造函数的.Prototype中工作

如何在下一个js中更改每个标记APEXCHARTS图表的 colored颜色

固定动态、self 调整的优先级队列

从异步操作返回对象

使用props 将VUE 3组件导入JS文件

AstroJS混合模式服务器终结点返回404

如果查询为空,则MongoDB将所有文档与$in匹配

ReactJS Sweep Line:优化SciChartJS性能,重用wasmContext进行多图表渲染

如何在Java脚本中添加一个可以在另一个面板中垂直调整大小的面板?

为什么我的InDesign Java脚本不能完全工作?