If you have followed the steps in Connecting Angular 1 and Angular 2 with UpgradeModule, you should now have a hybrid application that is capable of sharing different elements with the opposing framework.
If you are unfamiliar with Angular 2 components, it is recommended that you go through the components chapter before you proceed.
This recipe will allow you to fully utilize Angular 2 components inside an Angular 1 template.
The code, links, and a live example in relation to this recipe are available at .
Suppose you had the following Angular 2 component that you wanted to use in an Angular 1 application:
[app/article.component.ts] import {Component, Input} from '@angular/core'; @Component({ selector: 'ng2-article', template: ` <h1>{{title}}</h1> <p>Written by: {{author}}</p> ` }) export class ArticleComponent { @Input() author:string title:string = 'Unicycle Jousting Recognized as Olympic Sport'; }
Begin by completing the Connecting Angular 1 and Angular 2 with UpgradeModule recipe.
Angular 1 has no comprehension of how to utilize Angular 2 components. The existing Angular 2 framework will dutifully render it if given the opportunity, but the definition itself must be connected to the Angular 1 framework so that it may be requested when needed.
Begin by adding the component declarations to the module definition; this is used to link the two frameworks:
[app/app.module.ts] import {NgModule} from '@angular/core'; import {BrowserModule} from '@angular/platform-browser'; import {UpgradeModule} from '@angular/upgrade/static'; import {RootComponent} from './root.component'; import {ArticleComponent} from './article.component'; @NgModule({ imports: [ BrowserModule, UpgradeModule, ], declarations: [ RootComponent, ArticleComponent ], bootstrap: [ RootComponent ] }) export class Ng2AppModule { constructor(public upgrade: UpgradeModule){} }
This connects the component declaration to the Angular 2 context, but Angular 1 still has no concept of how to interface with it. For this, you'll need to use downgradeComponent()
to define the Angular 2 component as an Angular 1 directive. Give the Angular 1 directive a different HTML tag to render inside so you can be certain that it's Angular 1 doing the rendering and not Angular 2:
[main.ts] import {Component, Input} from '@angular/core'; import {downgradeComponent} from '@angular/upgrade/static'; import {Ng1AppModule} from './ng1.module'; @Component({ selector: 'ng2-article', template: ` <h1>{{title}}</h1> <p>Written by: {{author}}</p> ` }) export class ArticleComponent { @Input() author:string title:string = 'Unicycle Jousting Recognized as Olympic Sport'; } Ng1AppModule.directive( 'ng1Article', downgradeComponent({component: ArticleComponent}));
Finally, since this component has an input, you'll need to pass this value via a binding attribute. Even though the component is still being declared as an Angular 1 directive, you'll use the Angular 2 binding syntax:
[index.html] <!DOCTYPE html> <html> <head> <!-- Angular 2 scripts --> <script src="zone.js "></script> <script src="reflect-metadata.js"></script> <script src="system.js"></script> <script src="system-config.js"></script> </head> <body> <div ng-init="authorName='Jake Hsu'"> <ng1-article [author]="authorName"></ng1-article> </div> <root></root> </body> </html>
The input and output must be explicitly declared at the time of conversion:
[app/article.component.ts] import {Component, Input} from '@angular/core'; import {downgradeComponent} from '@angular/upgrade/static'; import {Ng1AppModule} from './ng1.module'; @Component({ selector: 'ng2-article', template: ` <h1>{{title}}</h1> <p>Written by: {{author}}</p> ` }) export class ArticleComponent { @Input() author:string title:string = 'Unicycle Jousting Recognized as Olympic Sport'; } Ng1AppModule.directive( 'ng1Article', downgradeComponent({ component: ArticleComponent, inputs: ['author'] }));
These are all the steps required. If done properly, you should see the component render along with the author's name being interpolated inside the Angular 2 component through Angular 1's ng-init
definition.
You are giving Angular 1 the ability to direct Angular 2 to a certain element in the DOM and say, "I need you to render here." Angular 2 still controls the component view and operation, and in every sense, the main thing we really care about is a full Angular 2 component adapted for use in an Angular 1 template.
downgradeComponent()
takes an object specifying the component as an argument and returns the function that Angular 1 is expecting for the directive definition.