美文网首页
修改 Angular Component 构造函数参数被认为是

修改 Angular Component 构造函数参数被认为是

作者: 华山令狐冲 | 来源:发表于2021-12-25 09:16 被阅读0次

修改构造函数参数被认为是 breaking change:

Making any changes to the class constructor signature. Note that super calls need to be updated in classes extending ours.

如果我们在构造函数里引入新的参数,这被认为是 breaking change:

对于升级到新次要版本以及之前通过使用较少参数调用 super() 构造函数在其代码库中扩展我们的服务的任何客户,这将导致 breaking change(特别是编译错误),例如在以下示例中 :

   export class CustomService extends SpartacusService {
     constructor(promotionService: PromotionService){
       super(promotionService); // <--------- wrong constructor signature
       /* customer's constructor logic here */
     }
   }

正确做法:

// TODO(#10946): make CartItemContextSource a required dependency
  constructor(
    promotionService: PromotionService,
    // eslint-disable-next-line @typescript-eslint/unified-signatures
    cartItemContextSource: CartItemContextSource
  );
  /**
   * @deprecated since 3.1
   */
  constructor(promotionService: PromotionService);
  constructor(
    protected promotionService: PromotionService,
    @Optional() protected cartItemContextSource?: CartItemContextSource
  ) {}

  /* ... */

  method() {
    console.log(this.cartItemContextSource?.item$);
  }

注意以下三点:

(1) 添加 ?使新的构造函数参数可选。否则,传递较少参数的客户将收到编译错误。
(2) 在类的逻辑中,允许新的构造函数参数为空或未定义。您可以通过使用可选链 (?.) 访问新依赖项的任何属性来实现此目的,例如 this.cartItemContextSource?.item$。如果不这样做,扩展我们的类并向 super() 构造函数传递较少参数的客户将在我们的逻辑中收到运行时错误,因为 this.cartItemContextSource 对象将是未定义的。
(3) 如果您的类可能未提供新的构造函数依赖项(例如,依赖项服务不是providedIn:'root',或者在DOM中有条件地提供),则在构造函数依赖项之前使用@Optional()。否则,当没有条件提供依赖时,客户将收到无法解析依赖的 Angular 运行时错误。在构造函数依赖项之前使用 @Optional() 告诉 Angular 在无法注入值时优雅地回退到 null。

除了上述要求,我们还鼓励您执行以下操作:

(1) 添加内联注释,例如 // TODO(#ticket-number): make X a required dependency,以引用下一个主要版本的计划工作。

(2) 在实现上方添加构造函数的两个替代声明。 最上面的声明必须是最新的。

这是因为,在使用 SSR 的生产构建中,只有第一个声明用于解决依赖关系。 将 @deprecated 自 X.Y 添加到您的 JSDoc 评论也很有帮助。 包含此内容后,客户的 IDE 可以警告他们正在使用的旧构造函数签名(参数较少)已被弃用,这可以促使他们尽早迁移到新签名。

Using the Inject Decorator for Dependencie

将 @Inject 用于依赖项时,不应包含任何构造函数声明。 相反,您应该只包含构造函数定义。

当您构建库时(例如,当您运行 ng build --prod core 时),ng-packagr 工具仅使用第一个构造函数声明来解析注入的依赖项,而忽略构造定义。 但是,构造函数声明中不支持 Inject 装饰器,因此它不能用于解析那里的依赖关系。 如果你包含一个带有依赖的构造函数声明,ng-packagr 工具将无法解析依赖,你会得到一个错误,如下所示:

ERROR: Internal error: unknown identifier []

一个错误的例子:

import { PLATFORM_ID } from '@angular/core';
/*...*/

  // Do not add any constructor declarations when using @Inject to resolve a dependency
  constructor(
    platformId: any, // this dependency will not be resolved, nor can it be fixed with @Inject, because the Inject decorator is not supported here!
    newService?: NewService
  ) {}
   constructor(
    protected platformId: any,
  ) {}

  constructor(
    @Inject(PLATFORM_ID) protected platformId: any,
    protected newService?: NewService
  ) {}

一个正确的例子:

import { PLATFORM_ID } from '@angular/core';
/*...*/

  constructor(
    @Inject(PLATFORM_ID) protected platformId: any,
    protected newService?: NewService
  ) {}

相关文章

网友评论

      本文标题:修改 Angular Component 构造函数参数被认为是

      本文链接:https://www.haomeiwen.com/subject/xcwsxrtx.html