【问题标题】:inject() must be called from an injection context必须从注入上下文调用 inject()
【发布时间】:2018-12-31 07:45:35
【问题描述】:

我正在尝试将我的 Angular 应用程序导出为 npm 模块以供其他应用程序使用,但遇到了一些困难。我无法在互联网上的其他任何地方找到此错误,我无能为力。

我遵循了这个教程:https://medium.com/@nikolasleblanc/building-an-angular-4-component-library-with-the-angular-cli-and-ng-packagr-53b2ade0701e

我使用 ng-packagr 将我的应用导出为 npm 模块。我可以从准系统测试应用上的本地文件夹成功安装它,但无法让它显示我的应用。

错误:

    AppComponent.html:1 ERROR Error: inject() must be called from an injection context
    at inject (core.js:1362)
    at ChangeStackService_Factory (template-wiz.js:2074)
    at _callFactory (core.js:8223)
    at _createProviderInstance (core.js:8181)
    at resolveNgModuleDep (core.js:8156)
    at NgModuleRef_.push../node_modules/@angular/core/fesm5/core.js.NgModuleRef_.get (core.js:8849)
    at resolveDep (core.js:9214)
    at createClass (core.js:9094)
    at createDirectiveInstance (core.js:8971)
    at createViewNodes (core.js:10191)

template-wiz.module.ts(正在导出的模块)

    import { NgModule, ChangeDetectorRef, ComponentFactoryResolver } from '@angular/core';
    import { TemplateWizComponent } from './template-wiz.component';
    import { BrowserModule } from '@angular/platform-browser';
    import { FormsModule } from '@angular/forms';
    import { HttpClientModule } from '@angular/common/http';
    import { BlockListDirective } from './Directives/block-list.directive';
    import { TemplateItemsDirective } from './Directives/template-items.directive';
    import { ContextMenuComponent, SeperatorComponent, DragBoxComponent, SnapLineComponent, PropertiesComponent, ToolboxComponent } from './Components'
    import { AddressBlockComponent, TextBlockComponent, ImageBlockComponent, DataBlockComponent } from './Data-Blocks';
    import { BlockFactoryService, BlockRegistryService, DisplayInfoService, MouseClickService, SavingService, SnapService, TextHelperService, UserModeService } from './Services';
    import { PageContextMenuComponent } from './Components/page-context-menu/page-context-menu.component';
    import { CamelToWordsPipe } from './Pipes/camel-to-words.pipe';
    import { PdfPublisherService } from './Services/pdf-publisher/pdf-publisher.service';
    import { GradientBlockComponent } from './Data-Blocks/gradient-block/gradient-block.component';
    import { PropToTypePipe } from './Pipes/prop-to-type.pipe';
    import { ShapeBlockComponent } from './Data-Blocks/shape-block/shape-block.component';
    import { CommonModule } from '@angular/common';
    import { ModuleWithProviders } from '@angular/compiler/src/core';


    @NgModule({
      imports: [
        CommonModule,
        FormsModule,
        HttpClientModule
      ],
      entryComponents: [
        AddressBlockComponent,
        ContextMenuComponent,
        DragBoxComponent,
        GradientBlockComponent,
        ImageBlockComponent,
        PageContextMenuComponent,
        SeperatorComponent,
        ShapeBlockComponent,
        SnapLineComponent,
        TextBlockComponent
      ],
      declarations: [
        TemplateWizComponent,
        DataBlockComponent,
        AddressBlockComponent,
        SeperatorComponent,
        BlockListDirective,
        TemplateItemsDirective,
        ImageBlockComponent,
        TextBlockComponent, DragBoxComponent,
        SnapLineComponent,
        ToolboxComponent,
        PropertiesComponent,
        ContextMenuComponent,
        PageContextMenuComponent,
        GradientBlockComponent,
        CamelToWordsPipe,
        PropToTypePipe,
        ShapeBlockComponent
      ],
      providers: [
        BlockFactoryService,
        BlockRegistryService,
        DisplayInfoService,
        MouseClickService,
        SavingService,
        SnapService,
        TextHelperService,
        UserModeService,
        PdfPublisherService
      ],
      //bootstrap: [TemplateWizComponent],
      exports: [
        TemplateWizComponent
      ]
    })
    export class TemplateWizModule {
      static forRoot(): ModuleWithProviders {
        return {
          ngModule: TemplateWizModule,
          providers: [
            ComponentFactoryResolver
          ]
        }
      }
    }

app.module.ts(使用我的模块的裸机测试应用程序)

    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { FormsModule } from '@angular/forms';
    import { HttpClientModule } from '@angular/common/http';
    import { AppComponent } from './app.component';
    import { TemplateWizModule } from 'template-wiz';

    @NgModule({
      declarations: [
        AppComponent,
      ],
      imports: [
        BrowserModule,
        FormsModule,
        TemplateWizModule.forRoot(),
        HttpClientModule
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule { }

任何帮助或指点都将不胜感激,谢谢。

【问题讨论】:

标签: angular typescript


【解决方案1】:

我有同样的错误。

我发现我是从@angular/core 导入Inject 而不是@angular/core/testing

希望有帮助!

【讨论】:

  • 我最终将它转换为 Angular 6 中的组件库,它最终工作得更好。会向其他人推荐相同的。不过,感谢您的洞察力
  • 我在进行单元测试,这个答案解决了我的问题
  • 魔鬼在细节中:)
【解决方案2】:

当我创建一个在其工厂中使用另一个 InjectionTokentree-shakable InjectionToken 时,我收到了错误消息 inject() must be called from an injection context,例如

import { InjectionToken } from '@angular/core';

import { dependeeToken } from './dependee.token';

export const dependingToken = new InjectionToken<string>('depending', {
  factory: () => inject(dependeeToken) + ' depending';
  providedIn: 'root',
});

相反,我将依赖 InjectionToken 的提供程序添加到 NgModule

import { NgModule } from '@angular/core';

import { dependeeToken } from './dependee.token';
import { dependingToken } from './depending.token';

@NgModule({
  providers: [
    {
      deps: [dependeeToken],
      provide: dependingToken,
      useFactory: dependee => dependee + ' depending',
    }
  ],
})
export class DependingModule {}

package.json摘录

{
  "dependencies": {
    "@angular/compiler": "6.1.9",
    "@angular/core": "6.1.9"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "0.8.4",
    "@angular/cli": "6.2.4",
    "@angular/compiler-cli": "6.1.9",
    "typescript": "2.9.2"
  }
}

【讨论】:

    【解决方案3】:

    为我解决的问题是使用 Injectable 装饰器中的 providedIn 属性,而不是在导致我出现此错误消息的服务提供商的应用程序模块中注册服务。

    @Injectable({
      providedIn: 'root'
    })
    export class HeroService {}
    

    【讨论】:

      【解决方案4】:

      在使用库时使用npm link 似乎有问题。

      解决方法:在客户端项目的 angular.json 文件中使用projects.$name.architect.build.options.preserveSymlinks: true,而不是库中。

      更多信息:https://github.com/angular/angular/issues/25813

      【讨论】:

      • 太棒了,它对我有用。此外,对我来说,这个问题只有在我们运行 ng serve 时才出现 --prod 标志。
      • 我花了一天多的时间寻找解决方案。这最终对我有用!谢谢!
      • 救命。我永远不会尝试preserveSymlinks,因为“必须从注入上下文调用inject()”错误。只是为了说清楚:更改是在客户端项目上进行的,而不是在 lib 项目上。
      • 非常感谢!这应该被标记为解决方案。
      • @jvinyard 请将此解决方案标记为已接受!
      【解决方案5】:

      同样的问题

      我的案例:当我使用 Mat Dialog 时

      import { Component, OnInit, Inject } from '@angular/core';
      
       constructor(
          @Inject(MAT_DIALOG_DATA) public data: any,
          public matDialogRef: MatDialogRef<MatConfirmDialogComponent>) { }
      

      inject 和 Inject 是不同的:

      inject 是函数,Inject 是接口

      我希望这可以帮助找到相同场景的人。

      【讨论】:

        【解决方案6】:

        使用ng build --prod 命令构建角度9.0.0-next.0 时出现此错误。降级到版本 ~8.2.8 使我的 Angular 应用程序再次工作。

        它在 ng serve 的开发中运行良好,所以它似乎与 Ivy 相关联。

        【讨论】:

          【解决方案7】:

          如果 Karma 出现测试错误,只需删除 de node_modules 文件夹并重新安装。

          【讨论】:

            【解决方案8】:

            这就是为我解决的问题:

            tsconfig.app.json 下的compilerOptions 下添加以下行:

            "paths": { "@angular/*": [ "../node_modules/@angular/*" ] }
            

            来源:https://github.com/angular/angular/issues/25813#issuecomment-500091900

            【讨论】:

            • 这对我来说绝对适用于 Webpack v4.43.0 和 Angular v8.2.14。
            • 与anguler 10合作
            • 在链接生成的客户端的 Angular 11 中不适合我。见stackoverflow.com/questions/65709951/…
            • 我可以确认这解决了我在 Angular 12 中的问题
            • 我也可以确认这解决了我从 ng11 更新到 ng12 后的问题
            【解决方案9】:

            我在测试 Angular 应用程序时遇到了类似的问题。该应用程序导入了一个使用 npm 从@bit 安装的服务。该服务依赖于 MatSnackBar,这似乎导致了与 OP 相同的错误。

            为了让测试运行,我在配置测试模块时实例化了服务。

            在下面的示例中,AsyncUIFeedbackService 是通过 npm 从 Bit 安装的。将useValue 设置为服务的新实例,并存根MatSnackBar 效果很好。

            await TestBed.configureTestingModule({
                  declarations: [GeneralInfoComponent],
                  providers: [
                    FormBuilder,
                    { provide : AsyncUIFeedbackService, 
                      useValue: new AsyncUIFeedbackService({} as MatSnackBar)}, // <----Create the service
                  ],
                  imports: [AsyncUIFeedbackModule]
                }).compileComponents();
            

            【讨论】:

              【解决方案10】:

              同样的问题,但我的情况更愚蠢......

              我将npm install something 放在错误的文件夹中。

              所以只需 rm 错误的“node_modules”和 npm install 到好文件夹 x)

              【讨论】:

                【解决方案11】:

                我发现我是从 @angular/core 而不是 @angular/core/testing 导入 Inject。

                【讨论】:

                  【解决方案12】:
                  我的情况是因为`test-setup.ts`中缺少此代码。 我只有前两行。
                  import 'jest-extended';
                  import 'jest-preset-angular/setup-jest';
                  
                  import { getTestBed } from '@angular/core/testing';
                  import {
                    BrowserDynamicTestingModule,
                    platformBrowserDynamicTesting,
                  } from '@angular/platform-browser-dynamic/testing';
                  
                  getTestBed().resetTestEnvironment();
                  getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), {
                    teardown: { destroyAfterEach: false },
                  });
                  

                  让它有点困难的是,即使添加了这段代码,我也遇到了一个不同的无用错误,因为它是一个 Angular 库包,有自己的 package.json,其中缺少依赖关系 @angular/platform-browser-dynamic

                  以上有帮助,但我再次删除了此代码。
                  真正有帮助的是https://stackoverflow.com/a/68718393/217408

                  一个可发布的包

                  • 不能有dependencies,只有peerDependencies
                  • npm install 不应运行。库不得包含 node_modules 目录。

                  dependenciesnode_modules 几个月以来一直运行良好,但突然开始失败,现在如果不修复上述问题,即使更旧的提交也无法运行。

                  【讨论】:

                    【解决方案13】:

                    我遇到了类似的问题。在带有 npm 链接的 Angular 应用程序中使用 Angular 库。

                    如前所述:“解决方案:使用 projects.$name.architect.build.options.preserveSymlinks: true 在客户端项目的 angular.json 文件中,而不是库中。”使用“ng serve”为应用程序提供服务时有效。

                    但是,当使用“ng test”对应用程序进行单元测试时,错误仍然存​​在。在此处的 angular.json 文件中添加 preserveSymLinks:

                    projects.$name.architect.test.options.preserveSymlinks: true

                    也解决了这个问题。

                    【讨论】:

                      猜你喜欢
                      • 2019-08-15
                      • 1970-01-01
                      • 2020-08-25
                      • 1970-01-01
                      • 2021-08-07
                      • 2020-06-26
                      • 2020-08-15
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多