【问题标题】:Correct use of Angular TypeScript constructor - Can't resolve all parameters for正确使用 Angular TypeScript 构造函数 - 无法解析所有参数
【发布时间】:2019-05-29 21:10:23
【问题描述】:
@Injectable({
  providedIn: 'root',
  /* useFactory: () => new MyService(MyAnotherService.myInteger) */
})
export class MyService{

  constructor(private someInteger?: number) {
    // doThings with someInteger
  }

--aot build 会抱怨Warning: Can't resolve all parameters for...

事实上,由于useFactory: () 部分,我们仍然能够正确运行我们的应用程序。但我不知道这是否正确

我们当然可以把构造函数改成

constructor(private anotherService?: MyAnotherService) {
        // doThings with anotherService
      }

要关闭构建警告, 但是我不认为MyService应该依赖于MyAnotherService,因为它可以只依赖于一个原语,这对代码的可重用性也很不利

在这种情况下最好的做法是什么?

我的想法是这样的。 Angular 使用 Decorator 来指示它是一个 Angular 组件(对吗?) 所以主逻辑体不应该总是耦合到 Angular DI 逻辑,特别是如果它是一个服务。我们可以拉取服务代码并将其插入其他地方(是否使用 DI)

【问题讨论】:

  • 你为什么要传递 'private someInteger?: number'
  • 这是我希望在构建阶段可用的配置之一,仅此而已。在 Typescript 中拥有那种构造函数是不正常的吗?
  • 构造函数一般只用于依赖注入
  • 您是否需要将此服务声明为 tree-shakable 提供者?
  • 如何创建该服务的实例?你总是让角度DI来做吗?那么如何提供整数参数呢?

标签: angular typescript


【解决方案1】:

您可以使用可选的注入令牌

token.ts

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

export const INTEGER_TOKEN= new InjectionToken<number>('IntegerToken');

app.module.ts

import {INTEGER_TOKEN} from './token';

@NgModule({
//...
  ],
  providers: [
    {
      provide: INTEGER_TOKEN,
      useValue: 1 //Or factory if you need one
    },

service.ts

import {INTEGER_TOKEN} from './token';

import {Injectable, Inject, Optional} from '@angular/core';


@Injectable({
  providedIn: 'root',

})
export class MyService{

  constructor(@Optional() @Inject(INTEGER_TOKEN) private someInteger?: number) {
    // doThings with someInteger
  }

【讨论】:

    【解决方案2】:

    通常的做法是在其中加入尽可能少的逻辑。 大多数时候构造函数是用来注入依赖的。

    constructor(private anotherService: AnotherService) {
        // **don't** do Things with anotherService
      }
    

    然后在其他函数中使用它

    ngOnInit() {
       this.anotherService.getValue().subscribe((value) => {
          // do something
       });
    }
    

    ngOnInit() 函数将在组件中的 DOM 创建、所有依赖项被注入并绑定所有输入时被调用。即使逻辑不依赖于 DOM、输入绑定或依赖注入,通常也会使用 ngOnInit()。

    【讨论】:

      【解决方案3】:

      考虑这些:

      1. 当遇到在开发人员的 ng serve 中有效但在 AOT 中无效的问题时,请打开 "strictMetadataEmit" : true 以获取有关问题的详细信息。
      2. 例如,AOT 不适用于箭头函数。
      3. @Optional() 用于optional dependencies

      【讨论】:

        【解决方案4】:

        只需删除“?”

        import {MyAnotherService} from '/pathto your service';
             constructor(private anotherService: MyAnotherService) {
                   //prodedures
                  }
        

        或参数:

        myVariable: any;
        constructor(private anotherService: MyAnotherService) {
        
        this.myVariable = [];
        }
        

        【讨论】:

          【解决方案5】:

          构造函数一般只用于依赖注入

           <my-component [state]="'joining'"></my-component>
          
              export class MyService{
            state: string;
                constructor() { 
                  console.log(this.state) // => undefined
                }
                ngOnInit() {
                  console.log(this.state) // => 'joining'
                }
              }
          

          【讨论】:

          • 您可以看到,在这种情况下,我正在尝试构建一个服务,@Input 装饰器只能与@Component 一起使用。我说的对吗?
          • 你可以像模型或变量一样使用它
          猜你喜欢
          • 2016-11-08
          • 1970-01-01
          • 1970-01-01
          • 2022-12-18
          • 2017-06-17
          • 2015-05-29
          • 1970-01-01
          • 1970-01-01
          • 2017-10-05
          相关资源
          最近更新 更多