W3cubDocs

/Angular 2 TypeScript

UpgradeModule

Experimental Class

What it does

Part of the upgrade/static library for hybrid upgrade apps that support AoT compilation

Allows Angular 1 and Angular 2+ components to be used together inside a hybrid upgrade application, which supports AoT compilation.

Specifically, the classes and functions in the upgrade/static module allow the following:

  1. Creation of an Angular 2+ directive that wraps and exposes an Angular 1 component so that it can be used in an Angular 2 template. See UpgradeComponent.
  2. Creation of an Angular 1 directive that wraps and exposes an Angular 2+ component so that it can be used in an Angular 1 template. See downgradeComponent.
  3. Creation of an Angular 2+ root injector provider that wraps and exposes an Angular 1 service so that it can be injected into an Angular 2+ context. See Upgrading an Angular 1 service below.
  4. Creation of an Angular 1 service that wraps and exposes an Angular 2+ injectable so that it can be injected into an Angular 1 context. See downgradeInjectable.
  5. Bootstrapping of a hybrid Angular application which contains both of the frameworks coexisting in a single application. See the example below.

Mental Model

When reasoning about how a hybrid application works it is useful to have a mental model which describes what is happening and explains what is happening at the lowest level.

  1. There are two independent frameworks running in a single application, each framework treats the other as a black box.
  2. Each DOM element on the page is owned exactly by one framework. Whichever framework instantiated the element is the owner. Each framework only updates/interacts with its own DOM elements and ignores others.
  3. Angular 1 directives always execute inside the Angular 1 framework codebase regardless of where they are instantiated.
  4. Angular 2+ components always execute inside the Angular 2+ framework codebase regardless of where they are instantiated.
  5. An Angular 1 component can be "upgraded"" to an Angular 2+ component. This is achieved by defining an Angular 2+ directive, which bootstraps the Angular 1 component at its location in the DOM. See UpgradeComponent.
  6. An Angular 2+ component can be "downgraded"" to an Angular 1 component. This is achieved by defining an Angular 1 directive, which bootstraps the Angular 2+ component at its location in the DOM. See downgradeComponent.
  7. Whenever an "upgraded"/"downgraded" component is instantiated the host element is owned by the framework doing the instantiation. The other framework then instantiates and owns the view for that component. a. This implies that the component bindings will always follow the semantics of the instantiation framework. b. The DOM attributes are parsed by the framework that owns the current template. So attributes in Angular 1 templates must use kebab-case, while Angular 1 templates must use camelCase. c. However the template binding syntax will always use the Angular 2+ style, e.g. square brackets ([...]) for property binding.
  8. Angular 1 is always bootstrapped first and owns the root component.
  9. The new application is running in an Angular 2+ zone, and therefore it no longer needs calls to $apply().

How to use

import {UpgradeModule} from '@angular/upgrade/static';

Example

Import the UpgradeModule into your top level Angular 2+ NgModule.

// This NgModule represents the Angular 2 pieces of the application
@NgModule({
  declarations: [Ng2HeroesComponent, Ng1HeroComponentWrapper],
  providers: [
    HeroesService,
    // Register an Angular 2+ provider whose value is the "upgraded" Angular 1 service
    {provide: 'titleCase', useFactory: (i: any) => i.get('titleCase'), deps: ['$injector']}
  ],
  // All components that are to be "downgraded" must be declared as `entryComponents`
  entryComponents: [Ng2HeroesComponent],
  // We must import `UpgradeModule` to get access to the Angular 1 core services
  imports: [BrowserModule, UpgradeModule]
})
class Ng2AppModule {
  ngDoBootstrap() { /* this is a placeholder to stop the boostrapper from complaining */
  }
}

Then bootstrap the hybrid upgrade app's module, get hold of the UpgradeModule instance and use it to bootstrap the top level Angular 1 module.

// First we bootstrap the Angular 2 HybridModule
// (We are using the dynamic browser platform as this example has not been compiled AoT)
platformBrowserDynamic().bootstrapModule(Ng2AppModule).then(ref => {
  // Once Angular 2 bootstrap is complete then we bootstrap the Angular 1 module
  const upgrade = ref.injector.get(UpgradeModule) as UpgradeModule;
  upgrade.bootstrap(document.body, [ng1AppModule.name]);
});

Upgrading an Angular 1 service

There is no specific API for upgrading an Angular 1 service. Instead you should just follow the following recipe:

Let's say you have an Angular 1 service:

// This Angular 1 service will be "upgraded" to be used in Angular 2+
ng1AppModule.factory(
    'titleCase',
    () => (value: string) => value.replace(/((^|\s)[a-z])/g, (_, c) => c.toUpperCase()));

Then you should define an Angular 2+ provider to be included in your NgModule providers property.

// Register an Angular 2+ provider whose value is the "upgraded" Angular 1 service
{provide: 'titleCase', useFactory: (i: any) => i.get('titleCase'), deps: ['$injector']}

Then you can use the "upgraded" Angular 1 service by injecting it into an Angular 2 component or service.

constructor(@Inject('titleCase') titleCase: (v: string) => string) {
  // Change all the hero names to title case, using the "upgraded" Angular 1 service
  this.heroes.forEach((hero: Hero) => hero.name = titleCase(hero.name));
}

Class Overview

class UpgradeModule {
  constructor(injector: Injector, ngZone: NgZone)
  
  
  $injector : any
  injector : Injector
  ngZone : NgZone
  bootstrap(element: Element, modules?: string[], config?: any)
}

Class Description

This class is an NgModule, which you import to provide Angular 1 core services, and has an instance method used to bootstrap the hybrid upgrade application.

Core Angular 1 services

Importing this NgModule will add providers for the core Angular 1 services to the root injector.

Bootstrap

The runtime instance of this class contains a bootstrap() method, which you use to bootstrap the top level Angular 1 module onto an element in the DOM for the hybrid upgrade app.

It also contains properties to access the root injector, the bootstrap NgZone and the Angular 1 $injector.

Annotations

@NgModule({providers: angular1Providers})

Constructor

constructor(injector: Injector, ngZone: NgZone)

Class Details

$injector : any

The Angular 1 $injector for the upgrade application.

injector : Injector

The root Injector for the upgrade application.

ngZone : NgZone

The bootstrap zone for the upgrade application

bootstrap(element: Element, modules?: string[], config?: any)

Bootstrap an Angular 1 application from this NgModule

exported from @angular/upgrade/static, defined in @angular/upgrade/src/aot/upgrade_module.ts

© 2010–2017 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://v2.angular.io/docs/ts/latest/api/upgrade/static/UpgradeModule-class.html