升级到Angular版本18
Sterling Store Engagement 已升级到 Angular 18 版本。 请确保将您的扩展程序迁移到Angular版本18。
开始之前
注: 如果您无法迁移到 Angular 版本 18,但又想在 Angular 版本 15 中修改扩展,则可以继续使用 24.3.9.2-10.0.2409.2 开发人员工具包构建自定义扩展。 要获得最新的功能、增强和修复,您必须升级到 Angular 18 版本。
- 您必须从 24.3.9.2-10.0.2409.2 或任何 Angular 版本 15 开发人员工具包中获得 Angular 版本 15 工作区。
- 请确保您使用的是
node.js版本 18.20.0。
关于此任务
注意 :请确保从 <WORKSPACE>/store-frontend-src 文件夹运行所有命令。
过程
- 在 packages/libs/styles/package.json 和 extensions/libs/styles/package.json 文件中,将node-sass更新为版本 8.0.0 ,然后运行以下命令之一:
yarn bootstrap - 通过运行以下命令将Angular核心和CLI升级到版本16:
ng update @angular/core@16 @angular/cli@16 --allow-dirty --force - 通过运行以下命令将Angular核心和CLI升级到版本17:
ng update @angular/core@17 @angular/cli@17 --allow-dirty --force - 通过运行以下命令将Angular核心和CLI升级到版本18:
ng update @angular/core@18 @angular/cli@18 --allow-dirty --force注意: 运行此命令时,您会遇到一个可选的迁移,以使用应用程序生成器use-application-builder,请按回车键继续 - 在扩展目录中的所有 app.component.ts 构造方法中搜索并用新代码替换现有代码。 如果没有出现该代码段,请继续执行步骤 6。以下代码展示了现有代码:
this.router.events.subscribe((event: RouterEvent) => { this.routingStateService.navigationInterceptor(event); });以下代码展示了新代码:this.router.events.pipe( filter((event: Event | RouterEvent): event is RouterEvent => event instanceof RouterEvent) ).subscribe((event: RouterEvent) => { this.routingStateService.navigationInterceptor(event); });然后,从 @angular/router 导入 Event ,从 rxjs/operators 导入 filter 。import { filter, take } from 'rxjs/operators'; import { Router, RouterEvent, Event } from '@angular/router'; - 如果您有 extended
packages/libs/common-components/src/lib/components/donut-chart/donut-chart.component.ts ,请搜索并用 donut-chart.component.ts 文件中的新代码替换现有代码。以下代码展示了现有代码:
const pie = d3.pie().value((d) => d.count).sort(null);以下代码展示了新代码:const pie = d3.pie().value((d) => d?.['count']).sort(null); - 在 angular.json 文件中,搜索 browserTarget 并将其替换为 buildTarget。
- 在最新的开发者工具包 25.1.3.0-10.0.2503.0 中,浏览到 extensions/libs/styles 目录,然后将 package.json 和 webpack.config.js 文件复制到扩展文件夹。
- 完成以下步骤,从最新的开发者工具包 25.1.3.0-10.0.2503.0 中设置新的工作区。
- 将 angular.json 文件从之前的工作区复制到新的工作区。
- 将已迁移的扩展从旧工作区复制到新工作区。
- 重新运行以下命令以测试扩展:
yarn bootstrapln -s <store-temp>/store-cli/schematics/node_modules <store-temp>/store-cli/node_modules在此之前运行命令时,请确保使用绝对路径。
- 将从应用程序提供的代码中接收的更改与扩展合并,以确保您使用的是最新版本的代码,并避免出现任何编译错误。
- 在合并更改时,请考虑下一组步骤。
- 在
RxJS的最新版本中,如果没有提供下一个方法的参数,TypeScript会显示错误信息。 如果不想传递参数,请使用 void 类型声明主题。 另外,如果主体从另一个来源发送值并被观察者整合,但您不想从一个来源发送任何值,可将 null 作为参数传递给 next 方法。 以下代码展示了现有代码:public addToCartSubject = new Subject<any>(); this.refreshParentComponent.next();以下代码展示了新代码:
public addToCartSubject = new Subject<void>(); this.refreshParentComponent.next(null); - ngbAccordion 在 版本的 ng-bootstrap 中从 更改为。 16.0.0 component directive 按照后面的示例,确保扩展名中出现的所有 ngbAccordion 都升级到 directive。
- 如以下示例所示,更改 component.html 文件中的手风琴代码。 以下代码说明了旧代码:
<ngb-accordion #acc="ngbAccordion" activeIds="{{activeIds}}" [attr.tid]="componentId+'filterStatus'"> <ngb-panel id="ngb-panel-assignto"> <ng-template ngbPanelTitle> <span [ngClass]="{' app-icon-open-chevron_down_14': isOpen(acc, 'ngb-panel-assignto'), 'app-icon-collapsed-chevron_right_14': !isOpen(acc, 'ngb-panel-assignto') }" class="app-glyphicons"></span> <span translate> filterOptions.LABEL_FilterGroupDisplayValueAssignTo</span> </ng-template> <ng-template ngbPanelContent> <isf-combo-box [attr.tid]="componentId+'filterAssignTo'" [searchText]="selectedUserName" [items]="userList" [columnName]="'name'" [selectedValues]="[selectedUserName]" [placeholder]="'filterOptions.LABEL_SelectAssociate'" [isItemSelected]="selectedUserName" (applySelection)="onSelection($event)" [resetValue]="resetComboBox"></isf-combo-box> </ng-template> </ngb-panel> </ngb-accordion>以下代码展示了新代码:
<div ngbAccordion #acc="ngbAccordion" [attr.tid]="componentId+'filterStatus'"> <div ngbAccordionItem="ngb-panel-assignto" id="ngb-panel-assignto" [collapsed]="!activeIds.includes('ngb-panel-assignto')"> <div ngbAccordionHeader> <button ngbAccordionButton> <span [ngClass]="{' app-icon-open-chevron_down_14': isOpen(acc, 'ngb-panel-assignto'), 'app-icon-collapsed-chevron_right_14': !isOpen(acc, 'ngb-panel-assignto') }" class="app-glyphicons"></span> <span translate> filterOptions.LABEL_FilterGroupDisplayValueAssignTo</span> </button> </div> <div ngbAccordionCollapse> <div ngbAccordionBody> <ng-template> <isf-combo-box [attr.tid]="componentId+'filterAssignTo'" [searchText]="selectedUserName" [items]="userList" [columnName]="'name'" [selectedValues]="[selectedUserName]" [placeholder]="'filterOptions.LABEL_SelectAssociate'" [isItemSelected]="selectedUserName" (applySelection)="onSelection($event)" [resetValue]="resetComboBox"></isf-combo-box> </ng-template> </div> </div> </div> </div> - 在 component.ts 文件中,删除导入的 NgbAccordion ,并从 @ng-bootstrap/ng-bootstrap 中添加 NgbAccordionDirective 。
import { NgbAccordionDirective } from '@ng-bootstrap/ng-bootstrap'; - 在 component.ts 文件中,修改 isOpen 函数,如下面的代码示例所示。
public isOpen(acc: NgbAccordion, panelId: string) { return (acc.activeIds.includes(panelId)); }更改如下:public isOpen(acc: NgbAccordionDirective, panelId: string) { return acc.isExpanded(panelId) } - PanelChange 事件已在最新的 ngbootsrap 中删除。 进行以下提到的更改:
- 如下例所示,在
component.html文件中将 panelChange 替换为 show :(panelChange)="setSelectedLocation($event)"替换如下:(show)="setSelectedLocation($event)" - 在 component.ts 文件中,更改 panelChange 事件处理函数,如下例所示:
public setSelectedLocation(event: NgbPanelChangeEvent) { if (UIUtil.isNotVoid(event.nextState)) { if (UIUtil.isNotVoid(event.panelId)) { this.selectedLocationId = event.panelId; this._setDefaultAttributeSet(this.selectedLocationId); } } else { this.selectedLocationId = ''; } }更改为public setSelectedLocation(panelId: string) { if (UIUtil.isNotVoid(panelId)) { this.selectedLocationId = panelId; this._setDefaultAttributeSet(this.selectedLocationId); } else { this.selectedLocationId = ''; } }
- 如下例所示,在
- 如以下示例所示,更改 component.html 文件中的手风琴代码。 以下代码说明了旧代码:
- 如果在引导程序的 navbar 中使用 ngbDropdown ,请将 display 属性设置为 dynamic ,如图所示。
<div ngbDropdown display="dynamic"></div>
- 在
- 运行以下命令启动应用程序:
yarn start-app注意: 运行yarn start-app命令时遇到以下错误,请从工作区删除 .angular 文件夹,然后重新运行该命令。Module not found: Error: node_modules/@angular-devkit/build-angular/node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js'