Книга: Angular 2 Cookbook
Назад: Connecting Angular 1 and Angular 2 with UpgradeModule
Дальше: Downgrade Angular 2 providers to Angular 1 services with downgradeInjectable

Downgrading Angular 2 components to Angular 1 directives with downgradeComponent

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.

Tip

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.

Note

The code, links, and a live example in relation to this recipe are available at .

Getting ready

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.

How to do it...

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.

How it works...

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.

Tip

downgradeComponent() takes an object specifying the component as an argument and returns the function that Angular 1 is expecting for the directive definition.

See also

  • Connecting Angular 1 and Angular 2 with UpgradeModule shows you how to run Angular 1 and 2 frameworks together
  • Downgrade Angular 2 providers to Angular 1 services with downgradeInjectable demonstrates how to use an Angular 2 service inside an Angular 1 application
Назад: Connecting Angular 1 and Angular 2 with UpgradeModule
Дальше: Downgrade Angular 2 providers to Angular 1 services with downgradeInjectable

thank you
Flame
cant read the code since it is all on a single line. Also this comments section is russian
Rakuneque
DATA COLLECTION AND ANALYSIS Two reviewers extracted data and assessed methodological quality independently lasix torsemide conversion Many others were in that space already