PR Close #18487 PR Close #18487
This commit is contained in:
parent
24e0c3d43d
commit
0b3d25d67e
|
@ -5,7 +5,7 @@
|
|||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {Component, Directive, DoCheck, ElementRef, EventEmitter, Inject, Injectable, Injector, Input, NgModule, OnChanges, OnDestroy, OnInit, Output, SimpleChanges} from '@angular/core';
|
||||
import {Component, Directive, ElementRef, EventEmitter, Inject, Injectable, Injector, Input, NgModule, Output, SimpleChanges} from '@angular/core';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
import {UpgradeComponent, UpgradeModule, downgradeComponent, downgradeInjectable} from '@angular/upgrade/static';
|
||||
|
@ -66,28 +66,18 @@ class HeroesService {
|
|||
// #docregion ng1-hero-wrapper
|
||||
// This Angular directive will act as an interface to the "upgraded" AngularJS component
|
||||
@Directive({selector: 'ng1-hero'})
|
||||
class Ng1HeroComponentWrapper extends UpgradeComponent implements OnInit, OnChanges, DoCheck,
|
||||
OnDestroy {
|
||||
class Ng1HeroComponentWrapper extends UpgradeComponent {
|
||||
// The names of the input and output properties here must match the names of the
|
||||
// `<` and `&` bindings in the AngularJS component that is being wrapped
|
||||
// TODO(issue/24571): remove '!'.
|
||||
@Input() hero !: Hero;
|
||||
// TODO(issue/24571): remove '!'.
|
||||
@Output() onRemove !: EventEmitter<void>;
|
||||
constructor(@Inject(ElementRef) elementRef: ElementRef, @Inject(Injector) injector: Injector) {
|
||||
|
||||
constructor(elementRef: ElementRef, injector: Injector) {
|
||||
// We must pass the name of the directive as used by AngularJS to the super
|
||||
super('ng1Hero', elementRef, injector);
|
||||
}
|
||||
|
||||
// For this class to work when compiled with AoT, we must implement these lifecycle hooks
|
||||
// because the AoT compiler will not realise that the super class implements them
|
||||
ngOnInit() { super.ngOnInit(); }
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) { super.ngOnChanges(changes); }
|
||||
|
||||
ngDoCheck() { super.ngDoCheck(); }
|
||||
|
||||
ngOnDestroy() { super.ngOnDestroy(); }
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
|
@ -107,11 +97,19 @@ class Ng1HeroComponentWrapper extends UpgradeComponent implements OnInit, OnChan
|
|||
// We must import `UpgradeModule` to get access to the AngularJS core services
|
||||
imports: [BrowserModule, UpgradeModule]
|
||||
})
|
||||
// #docregion bootstrap-ng1
|
||||
class Ng2AppModule {
|
||||
ngDoBootstrap() { /* this is a placeholder to stop the bootstrapper from complaining */
|
||||
// #enddocregion ng2-module
|
||||
constructor(private upgrade: UpgradeModule) {}
|
||||
|
||||
ngDoBootstrap() {
|
||||
// We bootstrap the AngularJS app.
|
||||
this.upgrade.bootstrap(document.body, [ng1AppModule.name]);
|
||||
}
|
||||
// #docregion ng2-module
|
||||
}
|
||||
// #enddocregion
|
||||
// #enddocregion bootstrap-ng1
|
||||
// #enddocregion ng2-module
|
||||
// #enddocregion
|
||||
|
||||
|
||||
|
@ -147,7 +145,7 @@ ng1AppModule.factory('heroesService', downgradeInjectable(HeroesService) as any)
|
|||
// #enddocregion
|
||||
|
||||
// #docregion ng2-heroes-wrapper
|
||||
// This is directive will act as the interface to the "downgraded" Angular component
|
||||
// This is directive will act as the interface to the "downgraded" Angular component
|
||||
ng1AppModule.directive('ng2Heroes', downgradeComponent({component: Ng2HeroesComponent}));
|
||||
// #enddocregion
|
||||
|
||||
|
@ -171,16 +169,12 @@ ng1AppModule.component('exampleApp', {
|
|||
<p class="extra">There are {{ $ctrl.heroesService.heroes.length }} heroes.</p>
|
||||
</ng2-heroes>`
|
||||
} as any);
|
||||
// #enddocregion
|
||||
// #enddocregion
|
||||
// #enddocregion
|
||||
|
||||
|
||||
// #docregion bootstrap
|
||||
// First we bootstrap the Angular HybridModule
|
||||
// (We are using the dynamic browser platform as this example has not been compiled AoT)
|
||||
platformBrowserDynamic().bootstrapModule(Ng2AppModule).then(ref => {
|
||||
// Once Angular bootstrap is complete then we bootstrap the AngularJS module
|
||||
const upgrade = ref.injector.get(UpgradeModule) as UpgradeModule;
|
||||
upgrade.bootstrap(document.body, [ng1AppModule.name]);
|
||||
});
|
||||
// #docregion bootstrap-ng2
|
||||
// We bootstrap the Angular module as we would do in a normal Angular app.
|
||||
// (We are using the dynamic browser platform as this example has not been compiled AoT.)
|
||||
platformBrowserDynamic().bootstrapModule(Ng2AppModule);
|
||||
// #enddocregion
|
||||
|
|
|
@ -100,11 +100,6 @@ export class UpgradeComponent implements OnInit, OnChanges, DoCheck, OnDestroy {
|
|||
* * The `name` parameter should be the name of the AngularJS directive.
|
||||
* * The `elementRef` and `injector` parameters should be acquired from Angular by dependency
|
||||
* injection into the base class constructor.
|
||||
*
|
||||
* Note that we must manually implement lifecycle hooks that call through to the super class.
|
||||
* This is because, at the moment, the AoT compiler is not able to tell that the
|
||||
* `UpgradeComponent`
|
||||
* already implements them and so does not wire up calls to them at runtime.
|
||||
*/
|
||||
constructor(private name: string, private elementRef: ElementRef, private injector: Injector) {
|
||||
this.helper = new UpgradeHelper(injector, name, elementRef);
|
||||
|
|
|
@ -22,13 +22,14 @@ import {NgAdapterInjector} from './util';
|
|||
* An `NgModule`, which you import to provide AngularJS core services,
|
||||
* and has an instance method used to bootstrap the hybrid upgrade application.
|
||||
*
|
||||
* *Part of the [upgrade/static](api?query=upgrade%2Fstatic)
|
||||
* *Part of the [upgrade/static](api?query=upgrade/static)
|
||||
* library for hybrid upgrade apps that support AoT compilation*
|
||||
*
|
||||
* The `upgrade/static` package contains helpers that allow AngularJS and Angular 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 directive that wraps and exposes an AngularJS component so
|
||||
* that it can be used in an Angular template. See `UpgradeComponent`.
|
||||
* 2. Creation of an AngularJS directive that wraps and exposes an Angular component so
|
||||
|
@ -39,8 +40,15 @@ import {NgAdapterInjector} from './util';
|
|||
* 4. Creation of an AngularJS service that wraps and exposes an Angular injectable
|
||||
* so that it can be injected into an AngularJS context. See `downgradeInjectable`.
|
||||
* 3. Bootstrapping of a hybrid Angular application which contains both of the frameworks
|
||||
* coexisting in a single application. See the
|
||||
* {@link UpgradeModule#examples example} below.
|
||||
* coexisting in a single application.
|
||||
*
|
||||
* @usageNotes
|
||||
*
|
||||
* ```ts
|
||||
* import {UpgradeModule} from '@angular/upgrade/static';
|
||||
* ```
|
||||
*
|
||||
* See also the {@link UpgradeModule#examples examples} below.
|
||||
*
|
||||
* ### Mental Model
|
||||
*
|
||||
|
@ -59,7 +67,7 @@ import {NgAdapterInjector} from './util';
|
|||
* 5. An AngularJS component can be "upgraded"" to an Angular component. This is achieved by
|
||||
* defining an Angular directive, which bootstraps the AngularJS component at its location
|
||||
* in the DOM. See `UpgradeComponent`.
|
||||
* 6. An Angular component can be "downgraded"" to an AngularJS component. This is achieved by
|
||||
* 6. An Angular component can be "downgraded" to an AngularJS component. This is achieved by
|
||||
* defining an AngularJS directive, which bootstraps the Angular component at its location
|
||||
* in the DOM. See `downgradeComponent`.
|
||||
* 7. Whenever an "upgraded"/"downgraded" component is instantiated the host element is owned by
|
||||
|
@ -68,20 +76,25 @@ import {NgAdapterInjector} from './util';
|
|||
* 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 AngularJS templates must use kebab-case, while AngularJS templates must
|
||||
* use camelCase.
|
||||
* attributes in AngularJS templates must use kebab-case, while AngularJS templates must use
|
||||
* camelCase.
|
||||
* c. However the template binding syntax will always use the Angular style, e.g. square
|
||||
* brackets (`[...]`) for property binding.
|
||||
* 8. Angular is bootstrapped first; AngularJS is bootstrapped second. AngularJS always owns the
|
||||
* root component of the application.
|
||||
* 9. The new application is running in an Angular zone, and therefore it no longer needs calls
|
||||
* to `$apply()`.
|
||||
* 9. The new application is running in an Angular zone, and therefore it no longer needs calls to
|
||||
* `$apply()`.
|
||||
*
|
||||
* ### Core AngularJS services
|
||||
* ### The `UpgradeModule` class
|
||||
*
|
||||
* This class is an `NgModule`, which you import to provide AngularJS core services,
|
||||
* and has an instance method used to bootstrap the hybrid upgrade application.
|
||||
*
|
||||
* #### Core AngularJS services
|
||||
* Importing this `NgModule` will add providers for the core
|
||||
* [AngularJS services](https://docs.angularjs.org/api/ng/service) to the root injector.
|
||||
*
|
||||
* ### Bootstrap
|
||||
* #### Bootstrap
|
||||
* The runtime instance of this class contains a {@link UpgradeModule#bootstrap `bootstrap()`}
|
||||
* method, which you use to bootstrap the top level AngularJS module onto an element in the
|
||||
* DOM for the hybrid upgrade app.
|
||||
|
@ -96,14 +109,17 @@ import {NgAdapterInjector} from './util';
|
|||
*
|
||||
* {@example upgrade/static/ts/module.ts region='ng2-module'}
|
||||
*
|
||||
* Then bootstrap the hybrid upgrade app's module, get hold of the `UpgradeModule` instance
|
||||
* and use it to bootstrap the top level [AngularJS
|
||||
* module](https://docs.angularjs.org/api/ng/type/angular.Module).
|
||||
* Then inject `UpgradeModule` into your Angular `NgModule` and use it to bootstrap the top level
|
||||
* [AngularJS module](https://docs.angularjs.org/api/ng/type/angular.Module) in the
|
||||
* `ngDoBootstrap()` method.
|
||||
*
|
||||
* {@example upgrade/static/ts/module.ts region='bootstrap'}
|
||||
* {@example upgrade/static/ts/module.ts region='bootstrap-ng1'}
|
||||
*
|
||||
* Finally, kick off the whole process, by bootstraping your top level Angular `NgModule`.
|
||||
*
|
||||
* {@example upgrade/static/ts/module.ts region='bootstrap-ng2'}
|
||||
*
|
||||
* {@a upgrading-an-angular-1-service}
|
||||
*
|
||||
* ### Upgrading an AngularJS service
|
||||
*
|
||||
* There is no specific API for upgrading an AngularJS service. Instead you should just follow the
|
||||
|
|
Loading…
Reference in New Issue