feat(upgrade): allow setting the angularjs lib at runtime (#15168)

This PR adds an ability to reset the angularjs library, which is often needed when Angular
is loaded lazily using RequireJS.
This commit is contained in:
Victor Savkin 2017-04-14 12:04:28 -04:00 committed by Tobias Bosch
parent 65af9641c2
commit 8ad464d90e
4 changed files with 87 additions and 16 deletions

View File

@ -201,6 +201,7 @@ function noNg() {
throw new Error('AngularJS v1.x is not loaded!'); throw new Error('AngularJS v1.x is not loaded!');
} }
let angular: { let angular: {
bootstrap: (e: Element, modules: (string | IInjectable)[], config: IAngularBootstrapConfig) => bootstrap: (e: Element, modules: (string | IInjectable)[], config: IAngularBootstrapConfig) =>
void, void,
@ -208,27 +209,62 @@ let angular: {
element: (e: Element | string) => IAugmentedJQuery, element: (e: Element | string) => IAugmentedJQuery,
version: {major: number}, resumeBootstrap?: () => void, version: {major: number}, resumeBootstrap?: () => void,
getTestability: (e: Element) => ITestabilityService getTestability: (e: Element) => ITestabilityService
} = <any>{
bootstrap: noNg,
module: noNg,
element: noNg,
version: noNg,
resumeBootstrap: noNg,
getTestability: noNg
}; };
try { try {
if (window.hasOwnProperty('angular')) { if (window.hasOwnProperty('angular')) {
angular = (<any>window).angular; setAngularLib((<any>window).angular);
} }
} catch (e) { } catch (e) {
// ignore in CJS mode. setAngularLib(<any>{
bootstrap: noNg,
module: noNg,
element: noNg,
version: noNg,
resumeBootstrap: noNg,
getTestability: noNg
});
}
/**
* Resets the AngularJS library.
*
* Used when angularjs is loaded lazily, and not available on `window`.
*
* @stable
*/
export function setAngularLib(ng: any): void {
angular = ng;
}
/**
* Returns the current version of the AngularJS library.
*
* @stable
*/
export function getAngularLib(): any {
return angular;
}
export function bootstrap(
e: Element, modules: (string | IInjectable)[], config: IAngularBootstrapConfig): void {
angular.bootstrap(e, modules, config);
}
export function module(prefix: string, dependencies?: string[]): IModule {
return angular.module(prefix, dependencies);
}
export function element(e: Element | string): IAugmentedJQuery {
return angular.element(e);
}
export function resumeBootstrap(): void {
angular.resumeBootstrap();
}
export function getTestability(e: Element): ITestabilityService {
return angular.getTestability(e);
} }
export const bootstrap = angular.bootstrap;
export const module = angular.module;
export const element = angular.element;
export const version = angular.version; export const version = angular.version;
export const resumeBootstrap = angular.resumeBootstrap;
export const getTestability = angular.getTestability;

View File

@ -12,6 +12,7 @@
* Entry point for all public APIs of the upgrade/static package, allowing * Entry point for all public APIs of the upgrade/static package, allowing
* Angular 1 and Angular 2+ to run side by side in the same application. * Angular 1 and Angular 2+ to run side by side in the same application.
*/ */
export {getAngularLib, setAngularLib} from './src/common/angular1';
export {downgradeComponent} from './src/common/downgrade_component'; export {downgradeComponent} from './src/common/downgrade_component';
export {downgradeInjectable} from './src/common/downgrade_injectable'; export {downgradeInjectable} from './src/common/downgrade_injectable';
export {VERSION} from './src/common/version'; export {VERSION} from './src/common/version';

View File

@ -12,7 +12,7 @@ import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import * as angular from '@angular/upgrade/src/common/angular1'; import * as angular from '@angular/upgrade/src/common/angular1';
import {$INJECTOR, INJECTOR_KEY} from '@angular/upgrade/src/common/constants'; import {$INJECTOR, INJECTOR_KEY} from '@angular/upgrade/src/common/constants';
import {UpgradeModule, downgradeInjectable} from '@angular/upgrade/static'; import {UpgradeModule, downgradeInjectable, getAngularLib, setAngularLib} from '@angular/upgrade/static';
import {bootstrap, html} from '../test_helpers'; import {bootstrap, html} from '../test_helpers';
@ -99,5 +99,33 @@ export function main() {
expect(runBlockTriggered).toBeTruthy(); expect(runBlockTriggered).toBeTruthy();
}); });
})); }));
it('should allow resetting angular at runtime', async(() => {
let wrappedBootstrapepedCalled = false;
const n: any = getAngularLib();
setAngularLib({
bootstrap: (...args: any[]) => {
wrappedBootstrapepedCalled = true;
n.bootstrap(...args);
},
module: n.module,
element: n.element,
version: n.version,
resumeBootstrap: n.resumeBootstrap,
getTestability: n.getTestability
});
@NgModule({imports: [BrowserModule, UpgradeModule]})
class Ng2Module {
ngDoBootstrap() {}
}
const ng1Module = angular.module('ng1Module', []);
bootstrap(platformBrowserDynamic(), Ng2Module, html('<div>'), ng1Module)
.then((upgrade) => { expect(wrappedBootstrapepedCalled).toEqual(true); });
}));
}); });
} }

View File

@ -9,6 +9,12 @@ export declare function downgradeComponent(info: {
/** @experimental */ /** @experimental */
export declare function downgradeInjectable(token: any): Function; export declare function downgradeInjectable(token: any): Function;
/** @stable */
export declare function getAngularLib(): any;
/** @stable */
export declare function setAngularLib(ng: any): void;
/** @experimental */ /** @experimental */
export declare class UpgradeComponent implements OnInit, OnChanges, DoCheck, OnDestroy { export declare class UpgradeComponent implements OnInit, OnChanges, DoCheck, OnDestroy {
constructor(name: string, elementRef: ElementRef, injector: Injector); constructor(name: string, elementRef: ElementRef, injector: Injector);