必须从注入上下文中调用inject()

时间:2018-07-23 19:22:21

标签: angular typescript

我试图将Angular应用程序导出为npm模块以供其他应用程序使用,但是遇到了一些困难。我无法在Internet上的其他任何地方找到此错误,这是我的机智。

我遵循了本教程: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 { }

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

11 个答案:

答案 0 :(得分:7)

我有同样的错误。

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

希望有帮助!

答案 1 :(得分:1)

这是为我解决的问题:

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

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

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

答案 2 :(得分:0)

创建tree-shakable InjectionToken并在其工厂中使用另一个inject() must be called from an injection context的{​​{3}}时收到错误消息InjectionToken,例如

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 :(得分:0)

为我解决的是使用Injectable装饰器中的providerIn属性,而不是在导致该错误消息的服务提供者的应用模块中注册该服务。

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

答案 4 :(得分:0)

在使用库时使用npm链接似乎是一个问题。

检查以下问题: https://github.com/angular/angular/issues/25813

扰流板: 在angular.json中使用“ projects。$ name.architect.build.options.preserveSymlinks:true”

答案 5 :(得分:0)

同一问题在这里

我的案例:当我使用Mat对话框时

import { Component, OnInit, Inject } from '@angular/core';

 constructor(
    @Inject(MAT_DIALOG_DATA) public data: any,
    public matDialogRef: MatDialogRef<MatConfirmDialogComponent>) { }

注入与注入不同:

inject是一个函数,Inject是一个接口

我希望这对来找相同场景的人有所帮助。

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

如果错误通过测试显示在Karma上,则只需删除de node_modules 文件夹并重新安装即可。

答案 8 :(得分:0)

注意:确保将keepSymlinks设置为true,解决了我们的问题

答案 9 :(得分:0)

我在测试 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 :(得分:0)

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

我将 ---------------------------------------- System information ---------------------------------------- Platform: Windows-10-10.0.16299-SP0 Python: 3.9.1 PyCharm: 2021.1.1 Pillow: 8.2.0 ---------------------------------------- 放在错误的文件夹中。

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