无法使 AngularJS 服务在 Angular 中工作
Unable to get AngularJS service working in Angular
我搜索了很多 posts 和官方 Angular 文档,但我无法获得 AngularJS 服务 运行ning Angular。我终于来到了这个页面 https://angular.io/api/upgrade/static/UpgradeModule#examples,它似乎准确地解释了我需要什么,但是在执行所有这些步骤时我得到:
ERROR 错误:在设置 AngularJS 注入器之前尝试获取它。
我的印象是这个例子不是很完整。例如。没有提示必须加载(旧的)AngularJS 框架。我的服务看起来像 angular.module('my-module').service('my-service', ...
,因此需要定义 angular
,否则我会收到错误消息。此外,许多示例假设 AngularJS 代码是用 TypeScript 编写的。在我的例子中,这不是真的(只是简单的 Javascript)。
不幸的是 Angular 9 @angular/upgrade
模块还有一个额外的问题,这个问题在任何地方都没有提到,只能通过在 tsconfig.app.json
中禁用新的 Ivy 编译器来解决,否则编译器会抛出 Error: Error on worker #1: Error: getInternalNameOfClass() called on a non-ES5 class: expected UpgradeComponent to have an inner class declaration
:
"angularCompilerOptions": {
"enableIvy": false
}
如果有人能 post 一个完整的例子,说明为了 运行 AngularJS 服务在 Angular 中必须做什么,我将不胜感激组件。
更新 [2020 年 7 月 6 日]
在这里您可以找到一个 GitHub 存储库,您可以克隆它来重现该行为:https://github.com/berkon/angularjs-service-upgrade-test. I should also mention that I'm using the Electron framework and started based on this repo https://github.com/maximegris/angular-electron 但我想这在这种情况下应该无关紧要。
我有同样的错误,我在我的应用程序中解决了它,但是我不记得为什么会发生这种情况(抱歉,那是很久以前的事了)。我不是在升级服务,而是在降级。
这是我的 app.module.ts 我已经在对实现此功能至关重要的部分添加了评论,我希望这里可能对您有所提示。请注意,我使用 Angular CLI 生成应用程序。
setAngularJSGlobal(angular);
// Configure the angularjs app (yours might be defined elsewhere)
const app = angular.module('app', [MyFormsModule, AngularMaterialModule]);
app.run(RunAddressAutocompleteConfig);
app.run(RunDynamicQueryConfig);
// Downgrade Angular AppComponent so AngularJS can render it after bootstrapping
// my app used an Angular component as the root
app.directive('appRoot', downgradeComponent({ component: AppComponent }));
// Downgrade Angular services
app.factory('api', downgradeInjectable(ApiService));
app.factory('dynamicQuery', downgradeInjectable(DynamicQueryService));
@NgModule({
declarations: [
AppComponent,
FormDirective,
FormPageComponent,
FormsListPageComponent,
RouterLinkPreserveQueryParamsDirective,
FormEmptyStatePageComponent,
],
imports: [BrowserModule, UpgradeModule, AppRoutingModule, HttpClientModule, CommonModule],
// This was absolutely necessary for bootstrapping my app in this way
// I encountered errors otherwise
providers: [
{
provide: '$scope',
useExisting: '$rootScope',
},
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
entryComponents: [AppComponent],
})
export class AppModule implements DoBootstrap {
constructor(private readonly upgrade: UpgradeModule) {}
ngDoBootstrap(appRef: ApplicationRef) {
this.upgrade.bootstrap(document.body, [app.name], { strictDi: true });
appRef.bootstrap(AppComponent);
}
}
index.html
<body>
<app-root></app-root>
</body>
我终于成功了!弄清楚这一切真的很麻烦。大多数教程中都没有提到很多东西,甚至在官方 Angular 指南中也只有代码片段,这让 Angular 新手很难猜出把所有这些东西放在哪里。 bootstraping 也没有正确解释。此外,所有教程都假设“旧的”AngularJS 代码已经用 TypeScript 编写,这使得找到正确的 way/order 到 load/bootstrap/import 所有这些东西变得更加困难。最后,@angular/upgrade 模块与 Angular 9 中新的 Ivy 编译器的组合似乎存在问题。它抛出下面提到的错误。因此必须禁用它才能正常工作。真的很痛苦!!!
大致是这些步骤:
- 安装
angular
和 @angular/upgrade
节点模块
- 加载所有
.js
模块,包括 AngularJS 在 angular.json
的 script
部分
- 通过手动从@NgModule 和bootstrap AngularJS 中删除
bootstrap
部分,通过ngDoBootstrap
中断常规Angular bootstrap 进程.首先 bootstrap
AngularJS,之后bootstrap AppComponent class。这样,该服务在 AppComponent 初始化时可用。否则会出现注入错误!
- 在
providers []
部分添加新提供商以访问新服务
- 现在可以在 AppComponent 的构造函数中注入新的(升级的)服务
手动执行以下所有步骤的工作量相当大,但我列出它们以供参考。在这里您可以找到一个 GitHub 存储库,您可以在其中克隆一个可用的应用程序。不要惊讶!这个 repo 使用 Electron 框架 (electronjs.org)。不过请放心,这对我的发现没有任何影响:https://github.com/berkon/angularjs-service-upgrade-test
这里是分步指南:
先决条件
执行npm install angular --save
执行npm install @angular/upgrade --save
在 tsconfig.app.json
中添加 "enableIvy": false
到 angularCompilerOptions
以避免得到:
Error: getInternalNameOfClass() called on a non-ES5 class: expected UpgradeComponent to have an inner class declaration
将 "node_modules/angular/angular.js"
和包含您的 AngularJS 服务(在本例中为 "src/app/angular-js-service.js"
)的 Javascript 文件添加到 scripts []
数组在angular.json
app.module.ts
将ApplicationRef
添加到@angular/core
的导入括号中
添加import { UpgradeModule } from '@angular/upgrade/static'
将 UpgradeModule
添加到 @NgModule
的 imports []
数组
从 @NgModule
中完全删除 bootstrap
部分并将其替换为:entryComponents: [AppComponent]
将其添加到 @NgModule
中的 providers []
数组,并确保将 myService
替换为您的服务的正确名称:
{ provide: 'myService', useFactory: (i: any) => { return i.get('myService') }, deps: ['$injector'] }
将AppModule
的构造函数替换为:
constructor ( public upgradeModule: UpgradeModule ) {}
将其添加到 AppModule
class 并确保将 ajsAppModule
替换为您的 AngularJS 主应用程序模块的名称:
ngDoBootstrap ( appRef: ApplicationRef ) {
this.upgradeModule.bootstrap(document.body, ['ajsAppModule'], { strictDi: true } )
appRef.bootstrap ( AppComponent )
}
app.component.ts
将 Inject
添加到 @angular/core
处的导入括号中
在 AppComponent
class 中将构造函数更改为此,并确保将 myService
替换为您的 AngularJS 服务的名称
constructor ( @Inject('myService') myService: any ) {
myService.doSomething()
}
我搜索了很多 posts 和官方 Angular 文档,但我无法获得 AngularJS 服务 运行ning Angular。我终于来到了这个页面 https://angular.io/api/upgrade/static/UpgradeModule#examples,它似乎准确地解释了我需要什么,但是在执行所有这些步骤时我得到:
ERROR 错误:在设置 AngularJS 注入器之前尝试获取它。
我的印象是这个例子不是很完整。例如。没有提示必须加载(旧的)AngularJS 框架。我的服务看起来像 angular.module('my-module').service('my-service', ...
,因此需要定义 angular
,否则我会收到错误消息。此外,许多示例假设 AngularJS 代码是用 TypeScript 编写的。在我的例子中,这不是真的(只是简单的 Javascript)。
不幸的是 Angular 9 @angular/upgrade
模块还有一个额外的问题,这个问题在任何地方都没有提到,只能通过在 tsconfig.app.json
中禁用新的 Ivy 编译器来解决,否则编译器会抛出 Error: Error on worker #1: Error: getInternalNameOfClass() called on a non-ES5 class: expected UpgradeComponent to have an inner class declaration
:
"angularCompilerOptions": {
"enableIvy": false
}
如果有人能 post 一个完整的例子,说明为了 运行 AngularJS 服务在 Angular 中必须做什么,我将不胜感激组件。
更新 [2020 年 7 月 6 日]
在这里您可以找到一个 GitHub 存储库,您可以克隆它来重现该行为:https://github.com/berkon/angularjs-service-upgrade-test. I should also mention that I'm using the Electron framework and started based on this repo https://github.com/maximegris/angular-electron 但我想这在这种情况下应该无关紧要。
我有同样的错误,我在我的应用程序中解决了它,但是我不记得为什么会发生这种情况(抱歉,那是很久以前的事了)。我不是在升级服务,而是在降级。
这是我的 app.module.ts 我已经在对实现此功能至关重要的部分添加了评论,我希望这里可能对您有所提示。请注意,我使用 Angular CLI 生成应用程序。
setAngularJSGlobal(angular);
// Configure the angularjs app (yours might be defined elsewhere)
const app = angular.module('app', [MyFormsModule, AngularMaterialModule]);
app.run(RunAddressAutocompleteConfig);
app.run(RunDynamicQueryConfig);
// Downgrade Angular AppComponent so AngularJS can render it after bootstrapping
// my app used an Angular component as the root
app.directive('appRoot', downgradeComponent({ component: AppComponent }));
// Downgrade Angular services
app.factory('api', downgradeInjectable(ApiService));
app.factory('dynamicQuery', downgradeInjectable(DynamicQueryService));
@NgModule({
declarations: [
AppComponent,
FormDirective,
FormPageComponent,
FormsListPageComponent,
RouterLinkPreserveQueryParamsDirective,
FormEmptyStatePageComponent,
],
imports: [BrowserModule, UpgradeModule, AppRoutingModule, HttpClientModule, CommonModule],
// This was absolutely necessary for bootstrapping my app in this way
// I encountered errors otherwise
providers: [
{
provide: '$scope',
useExisting: '$rootScope',
},
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
entryComponents: [AppComponent],
})
export class AppModule implements DoBootstrap {
constructor(private readonly upgrade: UpgradeModule) {}
ngDoBootstrap(appRef: ApplicationRef) {
this.upgrade.bootstrap(document.body, [app.name], { strictDi: true });
appRef.bootstrap(AppComponent);
}
}
index.html
<body>
<app-root></app-root>
</body>
我终于成功了!弄清楚这一切真的很麻烦。大多数教程中都没有提到很多东西,甚至在官方 Angular 指南中也只有代码片段,这让 Angular 新手很难猜出把所有这些东西放在哪里。 bootstraping 也没有正确解释。此外,所有教程都假设“旧的”AngularJS 代码已经用 TypeScript 编写,这使得找到正确的 way/order 到 load/bootstrap/import 所有这些东西变得更加困难。最后,@angular/upgrade 模块与 Angular 9 中新的 Ivy 编译器的组合似乎存在问题。它抛出下面提到的错误。因此必须禁用它才能正常工作。真的很痛苦!!!
大致是这些步骤:
- 安装
angular
和@angular/upgrade
节点模块 - 加载所有
.js
模块,包括 AngularJS 在angular.json
的 - 通过手动从@NgModule 和bootstrap AngularJS 中删除
bootstrap
部分,通过ngDoBootstrap
中断常规Angular bootstrap 进程.首先 bootstrap AngularJS,之后bootstrap AppComponent class。这样,该服务在 AppComponent 初始化时可用。否则会出现注入错误! - 在
providers []
部分添加新提供商以访问新服务 - 现在可以在 AppComponent 的构造函数中注入新的(升级的)服务
script
部分
手动执行以下所有步骤的工作量相当大,但我列出它们以供参考。在这里您可以找到一个 GitHub 存储库,您可以在其中克隆一个可用的应用程序。不要惊讶!这个 repo 使用 Electron 框架 (electronjs.org)。不过请放心,这对我的发现没有任何影响:https://github.com/berkon/angularjs-service-upgrade-test
这里是分步指南:
先决条件
执行
npm install angular --save
执行
npm install @angular/upgrade --save
在
tsconfig.app.json
中添加"enableIvy": false
到angularCompilerOptions
以避免得到:Error: getInternalNameOfClass() called on a non-ES5 class: expected UpgradeComponent to have an inner class declaration
将
"node_modules/angular/angular.js"
和包含您的 AngularJS 服务(在本例中为"src/app/angular-js-service.js"
)的 Javascript 文件添加到scripts []
数组在angular.json
app.module.ts
将
的导入括号中ApplicationRef
添加到@angular/core
添加
import { UpgradeModule } from '@angular/upgrade/static'
将
的UpgradeModule
添加到@NgModule
imports []
数组从
@NgModule
中完全删除bootstrap
部分并将其替换为:entryComponents: [AppComponent]
将其添加到
@NgModule
中的providers []
数组,并确保将myService
替换为您的服务的正确名称:{ provide: 'myService', useFactory: (i: any) => { return i.get('myService') }, deps: ['$injector'] }
将
AppModule
的构造函数替换为:constructor ( public upgradeModule: UpgradeModule ) {}
将其添加到
AppModule
class 并确保将ajsAppModule
替换为您的 AngularJS 主应用程序模块的名称:ngDoBootstrap ( appRef: ApplicationRef ) { this.upgradeModule.bootstrap(document.body, ['ajsAppModule'], { strictDi: true } ) appRef.bootstrap ( AppComponent ) }
app.component.ts
将
处的导入括号中Inject
添加到@angular/core
在
AppComponent
class 中将构造函数更改为此,并确保将myService
替换为您的 AngularJS 服务的名称constructor ( @Inject('myService') myService: any ) { myService.doSomething() }