无法使AngularJS服务在AngularJS中工作
我搜索了很多帖子和官方的AngularJS文档,但是我无法在AngularJS中运行AngularJS服务。我终于来到了这一页,它似乎准确地解释了我需要什么,但当我完成所有这些步骤时,我得到了: 错误:试图在设置AngularJS喷油器之前获取该喷油器。 我的印象是这个例子不太完整。例如,没有提示必须加载(旧)AngularJS框架。我的服务看起来像无法使AngularJS服务在AngularJS中工作,angularjs,angular,service,angular-upgrade,Angularjs,Angular,Service,Angular Upgrade,我搜索了很多帖子和官方的AngularJS文档,但是我无法在AngularJS中运行AngularJS服务。我终于来到了这一页,它似乎准确地解释了我需要什么,但当我完成所有这些步骤时,我得到了: 错误:试图在设置AngularJS喷油器之前获取该喷油器。 我的印象是这个例子不太完整。例如,没有提示必须加载(旧)AngularJS框架。我的服务看起来像angular.module('My-module')。服务('My-service',…,因此需要定义angular,否则我会得到一个错误。此外,
angular.module('My-module')。服务('My-service',…
,因此需要定义angular
,否则我会得到一个错误。此外,许多示例假设AngularJS代码是用TypeScript编写的。在我的例子中,这不是真的(只是普通的Javascript)
不幸的是,对于Angular 9,@Angular/upgrade
模块还有一个额外的问题,这个问题在任何地方都没有提到,只能通过在tsconfig.app.json
中禁用新的Ivy编译器来解决,否则编译器将在worker上抛出Error:Error#1:Error:getInternalNameOfClass()对非ES5类调用:预期UpgradeComponent具有内部类声明
:
"angularCompilerOptions": {
"enableIvy": false
}
如果有人能给出一个完整的例子,说明在AngularJS组件中运行AngularJS服务必须做些什么,我将不胜感激
更新[2020年7月6日]
在这里,您可以找到一个可以克隆的GitHub repo,以复制该行为:。我还应该提到,我使用的是Electron框架,并基于此repo启动,但我想在这种情况下,这并不重要。我遇到了同样的错误,并在我的应用程序中解决了它,但我记不起发生这种情况的确切原因(对不起,那是很久以前的事了)。我不是在升级服务,而是在降级 这是我的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
我终于让它工作起来了!把这一切弄清楚真的很麻烦。很多东西在大多数教程中都没有提到,甚至在官方的Angular指南中也只有一些代码片段,这使得Angular新手很难猜出这些东西放在哪里。此外,引导也没有正确解释。此外所有教程都假定“旧的”AngularJS代码已经是用TypeScript编写的,这使得找到正确的方式/顺序来加载/引导/导入所有这些东西变得更加困难。最后,Angular9中的@angular/upgrade模块与新的Ivy编译器相结合似乎出现了问题。它抛出了下面提到的错误。因此必须禁用它才能使事情正常进行真的很痛 因此,大致如下步骤:
- 安装
和angular
节点模块@angular/upgrade
- 在
angular.json
- 通过手动从@NgModule中删除
部分,并通过bootstrap
从@NgModule和bootstrap AngularJS中删除引导,中断常规的角度引导过程。第一次引导 AngularJS,之后引导AppComponent类。这样,服务在AppComponent初始化时可用。否则您将得到注入错误ngDoBootstrap
- 在
部分添加一个新的提供者,以访问新服务providers[]
- 现在,新的(升级的)服务可以注入AppComponent的构造函数中
- 执行npm安装-保存
- 执行
npm安装@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
- 将
和包含AngularJS服务的Javascript文件(在本例中为“node_modules/angular/angular.js”
)添加到“src/app/angular js service.js”
数组中脚本[]
angular.json
- 将
添加到ApplicationRef
@angular/core
- 从“@angular/upgrade/static”添加
import{UpgradeModule}
- 将
添加到UpgradeModule
的imports[]
数组中@NgModule
- 从
中完全删除@NgModule
部分,并将其替换为:bootstrap
entryComponents:[AppComponent]
- 将其添加到
中的@NgModule
数组中,并确保用正确的服务名称替换提供者[]
:myService
{ provide: 'myService', useFactory: (i: any) => { return i.get('myService') }, deps: ['$injector'] }
- 将
的构造函数替换为:AppModule
constructor ( public upgradeModule: UpgradeModule ) {}
- 将其添加到
类中,并确保将AppModule
替换为AngularJS主应用程序模块的名称:ajsAppModule
ngDoBootstrap ( appRef: ApplicationRef ) { this.upgradeModule.bootstrap(document.body, ['ajsAppModule'], { strictDi: true } ) appRef.bootstrap ( AppComponent ) }
- 将
添加到Inject
@angular/core
- 在
类中,将构造函数更改为this,并确保将AppComponent
替换为AngularJS服务的名称myService
constructor ( @Inject('myService') myService: any ) { myService.doSomething() }