Book Image

Angular 2 Cookbook

By : Patrick Gillespie, Matthew Frisbie
Book Image

Angular 2 Cookbook

By: Patrick Gillespie, Matthew Frisbie

Overview of this book

Angular 2 introduces an entirely new way to build applications. It wholly embraces all the newest concepts that are built into the next generation of browsers, and it cuts away all the fat and bloat from Angular 1. This book plunges directly into the heart of all the most important Angular 2 concepts for you to conquer. In addition to covering all the Angular 2 fundamentals, such as components, forms, and services, it demonstrates how the framework embraces a range of new web technologies such as ES6 and TypeScript syntax, Promises, Observables, and Web Workers, among many others. This book covers all the most complicated Angular concepts and at the same time introduces the best practices with which to wield these powerful tools. It also covers in detail all the concepts you'll need to get you building applications faster. Oft-neglected topics such as testing and performance optimization are widely covered as well. A developer that reads through all the content in this book will have a broad and deep understanding of all the major topics in the Angular 2 universe.
Table of Contents (18 chapters)
Angular 2 Cookbook
Credits
About the Author
About the Reviewer
www.PacktPub.com
Customer Feedback
Dedication
Preface

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 http://ngcookbook.herokuapp.com/1499/.

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