feat(browser): use AppModules for bootstrap in the browser
This introduces the `BrowserModule` to be used for long form bootstrap and offline compile bootstrap: ``` @AppModule({ modules: [BrowserModule], precompile: [MainComponent], providers: […], // additional providers directives: […], // additional platform directives pipes: […] // additional platform pipes }) class MyModule { constructor(appRef: ApplicationRef) { appRef.bootstrap(MainComponent); } } // offline compile import {bootstrapModuleFactory} from ‘@angular/platform-browser’; bootstrapModuleFactory(MyModuleNgFactory); // runtime compile long form import {bootstrapModule} from ‘@angular/platform-browser-dynamic’; bootstrapModule(MyModule); ``` The short form, `bootstrap(...)`, can now creates a module on the fly, given `directives`, `pipes, `providers`, `precompile` and `modules` properties. Related changes: - make `SanitizationService`, `SecurityContext` public in `@angular/core` so that the offline compiler can resolve the token - move `AnimationDriver` to `platform-browser` and make it public so that the offline compiler can resolve the token BREAKING CHANGES: - short form bootstrap does no longer allow to inject compiler internals (i.e. everything from `@angular/compiler). Inject `Compiler` instead. To provide custom providers for the compiler, create a custom compiler via `browserCompiler({providers: [...]})` and pass that into the `bootstrap` method.
This commit is contained in:
@ -1,8 +1,8 @@
|
||||
import {LowerCasePipe, NgIf} from '@angular/common';
|
||||
import {CompilerConfig} from '@angular/compiler';
|
||||
import {AppModule, AppModuleMetadata, Compiler, Component, ComponentFactoryResolver, ComponentRef, DebugElement, Host, Inject, Injectable, Injector, OpaqueToken, Optional, Provider, SelfMetadata, SkipSelf, SkipSelfMetadata, forwardRef, getDebugNode, provide} from '@angular/core';
|
||||
import {AppModule, AppModuleMetadata, Compiler, Component, ComponentFactoryResolver, ComponentRef, ComponentResolver, DebugElement, Host, Inject, Injectable, Injector, OpaqueToken, Optional, Provider, SelfMetadata, SkipSelf, SkipSelfMetadata, forwardRef, getDebugNode, provide} from '@angular/core';
|
||||
import {ComponentFixture} from '@angular/core/testing';
|
||||
import {beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal';
|
||||
import {AsyncTestCompleter, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal';
|
||||
|
||||
import {BaseException} from '../../src/facade/exceptions';
|
||||
import {ConcreteType, IS_DART, Type, stringify} from '../../src/facade/lang';
|
||||
@ -195,6 +195,26 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
}));
|
||||
checkNgIfAndLowerCasePipe(compFixture, compFixture.debugElement.children[0]);
|
||||
});
|
||||
|
||||
it('should provide a Compiler instance that uses the directives/pipes of the module', () => {
|
||||
let appModule = compiler.compileAppModuleSync(ModuleWithDirectivesAndPipes).create();
|
||||
let boundCompiler: Compiler = appModule.injector.get(Compiler);
|
||||
var cf = boundCompiler.compileComponentSync(CompUsingModuleDirectiveAndPipe);
|
||||
let compFixture = new ComponentFixture(cf.create(injector), null, false);
|
||||
checkNgIfAndLowerCasePipe(compFixture, compFixture.debugElement);
|
||||
});
|
||||
|
||||
it('should provide a ComponentResolver instance that uses the directives/pipes of the module',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
let appModule = compiler.compileAppModuleSync(ModuleWithDirectivesAndPipes).create();
|
||||
let boundCompiler: ComponentResolver = appModule.injector.get(ComponentResolver);
|
||||
boundCompiler.resolveComponent(CompUsingModuleDirectiveAndPipe).then((cf) => {
|
||||
let compFixture = new ComponentFixture(cf.create(injector), null, false);
|
||||
checkNgIfAndLowerCasePipe(compFixture, compFixture.debugElement);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
describe('providers', function() {
|
||||
@ -471,6 +491,19 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||
expect(injector.get('a')).toBe('aValue');
|
||||
expect(injector.get('someToken')).toBe('someValue');
|
||||
});
|
||||
|
||||
it('should override the providers of nested modules', () => {
|
||||
var injector = compiler
|
||||
.compileAppModuleSync(
|
||||
SomeModule, new AppModuleMetadata({
|
||||
providers: [{provide: 'someToken', useValue: 'someNewValue'}],
|
||||
modules: [ModuleWithProvider]
|
||||
}))
|
||||
.create()
|
||||
.injector;
|
||||
expect(injector.get('someToken')).toBe('someNewValue');
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -40,6 +40,10 @@ export function main() {
|
||||
var renderLog: RenderLog;
|
||||
var directiveLog: DirectiveLog;
|
||||
|
||||
function createCompFixture<T>(template: string): ComponentFixture<TestComponent>;
|
||||
function createCompFixture<T>(template: string, compType: ConcreteType<T>): ComponentFixture<T>;
|
||||
function createCompFixture<T>(
|
||||
template: string, compType: ConcreteType<T>, _tcb: TestComponentBuilder): ComponentFixture<T>;
|
||||
function createCompFixture<T>(
|
||||
template: string, compType: ConcreteType<T> = <any>TestComponent,
|
||||
_tcb: TestComponentBuilder = null): ComponentFixture<T> {
|
||||
@ -58,19 +62,23 @@ export function main() {
|
||||
return nodes.map(node => node.injector.get(dirType));
|
||||
}
|
||||
|
||||
function _bindSimpleProp<T>(bindAttr: string): ComponentFixture<TestComponent>;
|
||||
function _bindSimpleProp<T>(bindAttr: string, compType: ConcreteType<T>): ComponentFixture<T>;
|
||||
function _bindSimpleProp<T>(
|
||||
bindAttr: string, compType: ConcreteType<T> = <any>TestComponent): ComponentFixture<T> {
|
||||
var template = `<div ${bindAttr}></div>`;
|
||||
return createCompFixture(template, compType);
|
||||
}
|
||||
|
||||
function _bindSimpleValue(expression: any): ComponentFixture<TestComponent>;
|
||||
function _bindSimpleValue<T>(expression: any, compType: ConcreteType<T>): ComponentFixture<T>;
|
||||
function _bindSimpleValue<T>(
|
||||
expression: any, compType: ConcreteType<T> = <any>TestComponent): ComponentFixture<T> {
|
||||
return _bindSimpleProp(`[someProp]='${expression}'`, compType);
|
||||
}
|
||||
|
||||
function _bindAndCheckSimpleValue<T>(
|
||||
expression: any, compType: ConcreteType<T> = <any>TestComponent): string[] {
|
||||
function _bindAndCheckSimpleValue(
|
||||
expression: any, compType: ConcreteType<any> = TestComponent): string[] {
|
||||
var ctx = _bindSimpleValue(expression, compType);
|
||||
ctx.detectChanges(false);
|
||||
return renderLog.log;
|
||||
|
Reference in New Issue
Block a user