我正在通过Angular的upgrade guide来学习如何在Angular应用程序中嵌入AngularJS组件。我使用Angular CLI创建了一个简单的Angular应用程序,并添加了一个简单的AngularJS模块作为依赖项。
当我运行ng serve
时,应用程序编译时没有错误。但是,在运行时,我在控制台中收到此消息:
Error: Trying to get the AngularJS injector before it being set.
导致此错误的原因是什么,我该如何避免?我没有偏离升级指南中详述的步骤。
以下是我在Angular应用程序中升级AngularJS组件的方法:
// example.directive.ts
import { Directive, ElementRef, Injector } from '@angular/core';
import { UpgradeComponent } from '@angular/upgrade/static';
// this is the npm module that contains the AngularJS component
import { MyComponent } from '@my-company/module-test';
@Directive({
selector: 'my-upgraded-component'
})
export class ExampleDirective extends UpgradeComponent {
constructor(elementRef: ElementRef, injector: Injector) {
// the .injectionName property is the component's selector
// string; "my-component" in this case.
super(MyComponent.injectionName, elementRef, injector);
}
}
这是我的app.module.ts
:
// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { UpgradeModule } from '@angular/upgrade/static';
import { ExampleDirective } from './example.directive';
import { myModuleName } from '@my-company/module-test';
@NgModule({
declarations: [AppComponent, ExampleDirective],
imports: [BrowserModule, AppRoutingModule, UpgradeModule],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {
constructor(private upgrade: UpgradeModule) {}
ngDoBootstrap() {
this.upgrade.bootstrap(document.body, [myModuleName], {
strictDi: true
});
}
}
我正在使用Angular 5.2.0。
答案 0 :(得分:1)
我遇到了同样的问题,终于解决了。在引导混合的Angular / angularjs应用程序之前,需要遵循一些步骤。
安装UpgradeModule npm install @angular/upgrade
将“ CompanyModule”(注册了所有公司组件的模块)包装到新的angularjs模块(例如:Ng1Shared)中。如果您没有用于公司组件的模块,则必须创建它。比降级AppComponent如下所示。
const MyCompanyModule = angular
.module('MyCompanyModule', [])
.component('myComponent', MyComponent)
.name;
const Ng1Shared = angular
.module('Ng1Shared', [MyCompanyModule])
.directive('appRoot', downgradeComponent({ component: AppComponent }))
.name;
使用基本导入(BrowserModule,CommonModule,UpgradeModule)配置AppModule。提供angularjs的Injector到Angular;声明一个“ entryComponent”并删除AppComponent的默认引导程序。
@NgModule({
imports: [BrowserModule, CommonModule, UpgradeModule],
declarations: [AppComponent],
providers: [{provide: '$scope', useExisting: '$rootScope'}], // REQUIRED
entryComponents: [AppComponent], // ADD AN ENTRY COMPONENT
// bootstrap: [AppComponent] MUST BE REMOVED
})
使用UpgradeModule本身提供的功能全局设置angularjs,并使用@ angular / core提供的DoBootstrap方法手动引导Angular。
export class AppModule implements DoBootstrap {
constructor(private upgrade: UpgradeModule) { }
public ngDoBootstrap(app: any): void {
setAngularJSGlobal(angular);
this.upgrade.bootstrap(document.body, [Ng1Shared], { strictDi: false });
app.bootstrap(AppComponent);
}
}
为每个angularjs组件创建一个包装指令,并将其添加到AppModule的声明数组中。
@Directive({
selector: 'my-component'
})
export class MyComponentWrapper extends UpgradeComponent {
@Input() title: string;
constructor(elementRef: ElementRef, injector: Injector) {
super('myComponent', elementRef, injector);
}
}
我写了一个简单的example available on stackblitz。 出于示例目的,我将angularjs MyCompanyModule添加到另一个名为Ng1Module的angularjs模块中。如您所见,angularjs和angular组件之间的属性绑定也可以正常工作。
我希望它会有用。
答案 1 :(得分:0)
https://github.com/angular/angular/issues/23141#issuecomment-379493753
你无法直接引导包含的Angular组件 在引导AngularJS之前升级了组件。相反,你可以 降级AppComponent并让它作为一部分进行自举 AngularJS应用程序的一部分:
https://stackblitz.com/edit/angular-djb5bu?file=app%2Fapp.module.ts
答案 2 :(得分:0)
尝试像这样将entryComponents添加到您的AppModule中:
...
@NgModule({
declarations: [AppComponent, ExampleDirective],
imports: [BrowserModule, AppRoutingModule, UpgradeModule],
entryComponents: [
AppComponent // Don't forget this!!!
],
providers: [],
// bootstrap: [AppComponent] // Delete or comment this line
})
...