npx @angular/cli new your-project-name
Note: Can optionally add --routing
flag to make part 3 a bit easier
npm install --save angular @angular/upgrade
npm install --save-dev @types/angular # optional for nice ts features (like autocomplete)
Adding some styling to make it easier to differentiate Angular and AngularJs components
.comp {
margin: 5px;
padding: 5px;
border: dashed 2px;
}
.ng {
border-color: #FF2829;
}
.ajs {
border-color: #1C446D;
}
<body class="comp ajs" style="text-align:center">
<h2>AngularJs Root</h2>
<app-root></app-root>
</body>
Note: We will only show some important imports in this guide. All other imports can be auto-imported by your IDE. You can also check the source code to see the full file.
import * as angular from 'angular';
export const legacyApp = angular.module('legacyApp', []);
This component will be our top level AngularJs Component.
export const LEGACY_APP_COMP_SELECTOR = 'legacyAppComp';
legacyApp.component(LEGACY_APP_COMP_SELECTOR, {
template: `
<div class="comp ajs">
<h2>Legacy App Component</h2>
<div>
`,
controller: () => console.log('Legacy App Controller'),
});
legacy.app.component.upgrade.ts
// We upgrade it so we can use it in our Angular app
@Directive({
selector: 'legacy-app-upgrade' // tslint:disable-line
})
export class LegacyAppUpgradeDirective extends UpgradeComponent {
constructor(elementRef: ElementRef, injector: Injector) {
super(LEGACY_APP_COMP_SELECTOR, elementRef, injector);
}
}
// IMPORTANT: This is necessary because:
// "AngularJS is always bootstrapped first and owns the root component."
// See: https://angular.io/api/upgrade/static/UpgradeModule
legacyApp.directive('appRoot',
downgradeComponent({
component: AppComponent,
outputs: ['callback']
}) as angular.IDirectiveFactory
);
// Import legacy files here
import './legacy.app.component';
import './downgrade';
import './app.component.downgrade';
Add the following line to your main.ts
:
setAngularJSGlobal(angular); // Make AngularJS avaiable globally
import './legacy/'; // imported so legacy files are bundled
@NgModule({
declarations: [
AppComponent,
// Import the upgraded legacyApp so Angular knows about it
// and we can use it in our app component
LegacyAppUpgradeDirective
],
imports: [
BrowserModule,
UpgradeModule // Add this so Angular can use the Upgrade module
],
providers: [],
// VERY IMPORTANT to change this from `bootstrap` to `entryComponents`!
// This is so we can manually bootstrap our app
entryComponents: [ AppComponent ]
})
export class AppModule {
constructor(private upgrade: UpgradeModule) { }
ngDoBootstrap() {
// Once Angular bootstrap is complete then we manually bootstrap the AngularJS module
this.upgrade.bootstrap(document.body, [legacyApp.name], { strictDi: true });
// Note: The AngualrJs bootstrapping could also be done in the `main.ts`.
// You may see others do it that way.
}
}
<div class="comp ng">
<h2>{{ title }}</h2>
<legacy-app-upgrade></legacy-app-upgrade>
</div>
npm start -- --open
Now you should have your hyrbrid app sucessfully running! :)
As you can see in the below image, AngularJs owns the root component, then we have our downgraded App Component, then the upgraded Legacy App Component.