如何使Angular2 + Router在Angular2 + / AngularJS混合应用程序上工作?
我正在研究 Angular的升级指南,以了解如何在Angular应用程序中嵌入AngularJS指令。我已经使用Angular CLI创建了一个简单的Angular应用程序,并添加了一个非常简单的AngularJS模块作为依赖项。
由于我已向Angular添加 RouterModule ,因此出现以下错误:
ERROR Error: Uncaught (in promise): Error: Trying to get the AngularJS injector before it being set.
Router Event: NavigationError
NavigationError(id: 1, url: '/', error: Error: Trying to get the AngularJS injector before it being set.)
NavigationError {id: 1, url: "/", error: Error: Trying to get the AngularJS injector before it being set.
at injectorFactory (http://loca…}
我的猜测是,问题出在我在Angular <router-link>
内显示一些升级版指令
这是我在Angular应用中升级AngularJS组件的方式:
// ng1.component.wrapper.ts
import { Directive, ElementRef, Injector, Input } from '@angular/core';
import { UpgradeComponent } from '@angular/upgrade/static';
@Directive({ selector: 'ng1' })
export class Ng1ComponentWrapper extends UpgradeComponent {
@Input() value1: string;
@Input() value2: string;
constructor(elementRef: ElementRef, injector: Injector) {
super('ng1', elementRef, injector);
}
}
这是我的app.module.ts
:
// app.module.ts
// Import AngularJS app
import '../ng1/ng1.module';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { UpgradeModule, downgradeComponent } from '@angular/upgrade/static';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
// -----------------------------
// ---- Upgraded components ----
// -----------------------------
import { Ng1ComponentWrapper } from '../ng1/ng1.component.wrapper';
// -----------------------------
// ---- Downgrade components ----
// -----------------------------
import { NG1_APP_MODULE_NAME } from '../ng1/ng1.module';
declare var angular: any;
angular.module(NG1_APP_MODULE_NAME)
.directive('appRoot', downgradeComponent({ component: AppComponent }))
@NgModule({
declarations: [
AppComponent,
Ng1ComponentWrapper
],
imports: [
AppRoutingModule,
BrowserModule,
UpgradeModule,
],
providers: [],
bootstrap: [ AppComponent ],
})
export class AppModule {
constructor(public upgrade: UpgradeModule) {}
}
这是main.ts
文件,我在其中引导Angular和AngularJS应用
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
import { NG1_APP_MODULE_NAME } from './ng1/ng1.module';
import { setUpLocationSync } from '@angular/router/upgrade';
if (environment.production) {
enableProdMode();
}
// This is the entry point for the AngularJS/Angular hybrid application.
// It bootstraps the Angular module 'AppModule', which in turn bootstraps
// the AngularJS module.
platformBrowserDynamic().bootstrapModule(AppModule)
.then(ref => {
console.log('Angular app bootstrapped !')
const upgrade = (<any>ref.instance).upgrade;
upgrade.bootstrap(document.body, [NG1_APP_MODULE_NAME]);
console.log('AngularJS app bootstrapped !');
setUpLocationSync(upgrade);
})
.catch(err => console.error('An error occured while bootstrapping the Angular app', err));
这是主要的AngularJS模块文件ng1.module.ts
'use strict';
import 'angular';
import 'xcomponent-widgets/common-module';
import { Ng1Component } from './ng1.component';
export const NG1_APP_MODULE_NAME = 'test-webapp';
declare var angular: any;
angular.module(NG1_APP_MODULE_NAME, [
'common-module'
])
.config(['$locationProvider', ($locationProvider) => {
$locationProvider.html5Mode(true);
}])
.component('ng1', Ng1Component);
最后是我的路由器
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { Ng1Component } from './component/ng1.component.ts';
export const appRoutes: Routes = [
{
path: 'test',
component: Ng1ComponentWrapper,
data: { title: 'Test' }
},
{ path: 'not-found', component: NotFoundComponent },
{ path: '', redirectTo: 'test', pathMatch: 'full' }, // Redirect to homepage by default
{ path: '**', redirectTo: 'not-found', pathMatch: 'full' } // If no route defined, redirect to page not found
];
@NgModule({
imports: [ RouterModule.forRoot(appRoutes, { enableTracing: true, useHash: false }) ],
exports: [ RouterModule ]
})
export class AppRoutingModule {}
Ng1Component
使用Ng1ComponentWrapper
的升级指令
我正在使用Angular 7.1.4和AngularJS 1.6.4
答案 0 :(得分:0)
我找到了解决方法。
问题在于,在AngularJS完全加载之前,RouterModule正在初始化导航。
我在路由器文件中添加了initialNavigation: false
@NgModule({
imports: [ RouterModule.forRoot(appRoutes, {
enableTracing: true,
useHash: false,
initialNavigation: false
}) ],
exports: [ RouterModule ]
})
export class AppRoutingModule {}
当AngularJS加载后,我调用了函数router.initialNavigation()
:
platformBrowserDynamic().bootstrapModule(AppModule)
.then(ref => {
console.log('Angular app bootstrapped !');
const upgrade = (<any>ref.instance).upgrade;
const router = (<any>ref.instance).router;
upgrade.bootstrap(document.body, [NG1_APP_MODULE_NAME]);
console.log('AngularJS app bootstrapped !');
setUpLocationSync(upgrade);
router.initialNavigation();
})
.catch(err => console.error('An error occured while bootstrapping the Angular app', err));
我希望它会对其他人有所帮助