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

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: 修改 Angular Component 构造函数参数被认为是 breaking change

修改构造函数参数被认为是 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
  ) {}


相关文章
|
2月前
|
Web App开发 UED 开发者
谈谈企业级 Angular 应用的二次开发 - 基于 Angular Component 替换的 Extensibility 支持案例介绍
谈谈企业级 Angular 应用的二次开发 - 基于 Angular Component 替换的 Extensibility 支持案例介绍
|
2月前
|
编译器 API 开发者
Angular Component ɵcmp 属性的含义和使用场合介绍
Angular Component ɵcmp 属性的含义和使用场合介绍
|
2月前
|
API 开发者
Angular Component class ɵfac 的属性介绍
Angular Component class ɵfac 的属性介绍
|
2月前
【超实用】Angular如何修改当前页面网页浏览器url后面?param1=xxx&param2=xxx参数(多用于通过浏览器地址参数保存用户当前操作状态的需求),实现监听url路由切换、状态变化。
【超实用】Angular如何修改当前页面网页浏览器url后面?param1=xxx&param2=xxx参数(多用于通过浏览器地址参数保存用户当前操作状态的需求),实现监听url路由切换、状态变化。
|
2月前
Angular多个页面引入同一个组件报错The Component ‘MyComponentComponent‘ is declared by more than one NgModule怎么办?
Angular多个页面引入同一个组件报错The Component ‘MyComponentComponent‘ is declared by more than one NgModule怎么办?
|
2月前
|
JavaScript
Angular Component 内 set 关键字的使用
Angular Component 内 set 关键字的使用
|
2月前
|
存储 前端开发 API
浅谈 Angular 应用前端消息显示机制的一个实际需求
浅谈 Angular 应用前端消息显示机制的一个实际需求
|
2月前
|
设计模式 JavaScript 前端开发
什么是 Angular 应用里的 Custom provider
什么是 Angular 应用里的 Custom provider
|
2月前
|
JavaScript 前端开发 架构师
Angular进阶:理解RxJS在Angular应用中的高效运用
RxJS(Reactive Extensions for JavaScript)是JavaScript的一个响应式编程库,特别适用于处理异步数据流。
40 0
|
2月前
|
JavaScript 前端开发
Angular.js 应用中数据模式的删除操作实现
Angular.js 应用中数据模式的删除操作实现