feat(upgrade): support downgrading multiple modules (#26217)

Currently, calling `downgradeModule()` more than once is not supported.
If one wants to downgrade multiple Angular modules, they can create a
"super-module" that imports all the rest and downgrade that.

This commit adds support for downgrading multiple Angular modules. If
multiple modules are downgraded, then one must explicitly specify the
downgraded module that each downgraded component or injectable belongs
to, when calling `downgradeComponent()` and `downgradeInjectable()`
respectively.

No modification is needed (i.e. there is no need to specify a module for
downgraded components and injectables), if an app is not using
`downgradeModule()` or if there is only one downgraded Angular module.

Fixes #26062

PR Close #26217
This commit is contained in:
George Kalpakas
2018-10-02 21:16:18 +03:00
committed by Kara Erickson
parent 6c5c97b2f9
commit 93837e9545
10 changed files with 273 additions and 20 deletions

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, ApplicationRef, Component, DoCheck, Inject, Injector, Input, NgModule, NgZone, OnChanges, OnDestroy, OnInit, StaticProvider, ViewRef, destroyPlatform} from '@angular/core';
import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, ApplicationRef, Component, DoCheck, Inject, Injector, Input, NgModule, NgZone, OnChanges, OnDestroy, OnInit, StaticProvider, Type, ViewRef, destroyPlatform, getPlatform} from '@angular/core';
import {async, fakeAsync, tick} from '@angular/core/testing';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
@ -25,6 +25,58 @@ withEachNg1Version(() => {
beforeEach(() => destroyPlatform());
it('should support multiple downgraded modules', async(() => {
@Component({selector: 'ng2A', template: 'a'})
class Ng2ComponentA {
}
@Component({selector: 'ng2B', template: 'b'})
class Ng2ComponentB {
}
@NgModule({
declarations: [Ng2ComponentA],
entryComponents: [Ng2ComponentA],
imports: [BrowserModule],
})
class Ng2ModuleA {
ngDoBootstrap() {}
}
@NgModule({
declarations: [Ng2ComponentB],
entryComponents: [Ng2ComponentB],
imports: [BrowserModule],
})
class Ng2ModuleB {
ngDoBootstrap() {}
}
const doDowngradeModule = (module: Type<any>) => {
const bootstrapFn = (extraProviders: StaticProvider[]) =>
(getPlatform() || platformBrowserDynamic(extraProviders)).bootstrapModule(module);
return downgradeModule(bootstrapFn);
};
const downModA = doDowngradeModule(Ng2ModuleA);
const downModB = doDowngradeModule(Ng2ModuleB);
const ng1Module = angular.module('ng1', [downModA, downModB])
.directive('ng2A', downgradeComponent({
component: Ng2ComponentA,
downgradedModule: downModA, propagateDigest,
}))
.directive('ng2B', downgradeComponent({
component: Ng2ComponentB,
downgradedModule: downModB, propagateDigest,
}));
const element = html('<ng2-a></ng2-a> | <ng2-b></ng2-b>');
angular.bootstrap(element, [ng1Module.name]);
// Wait for the module to be bootstrapped.
setTimeout(() => expect(element.textContent).toBe('a | b'));
}));
it('should support downgrading a component and propagate inputs', async(() => {
@Component(
{selector: 'ng2A', template: 'a({{ value }}) | <ng2B [value]="value"></ng2B>'})