feat(core): allow custom selector when bootstrapping components (#15668)
- fixes #7136 PR Close #15668
This commit is contained in:
parent
cb384e8ed3
commit
900a88b15d
@ -358,10 +358,15 @@ export abstract class ApplicationRef {
|
|||||||
* specified application component onto DOM elements identified by the [componentType]'s
|
* specified application component onto DOM elements identified by the [componentType]'s
|
||||||
* selector and kicks off automatic change detection to finish initializing the component.
|
* selector and kicks off automatic change detection to finish initializing the component.
|
||||||
*
|
*
|
||||||
|
* Optionally, a component can be mounted onto a DOM element that does not match the
|
||||||
|
* [componentType]'s selector.
|
||||||
|
*
|
||||||
* ### Example
|
* ### Example
|
||||||
* {@example core/ts/platform/platform.ts region='longform'}
|
* {@example core/ts/platform/platform.ts region='longform'}
|
||||||
*/
|
*/
|
||||||
abstract bootstrap<C>(componentFactory: ComponentFactory<C>|Type<C>): ComponentRef<C>;
|
abstract bootstrap<C>(
|
||||||
|
componentFactory: ComponentFactory<C>|Type<C>,
|
||||||
|
rootSelectorOrNode?: string|any): ComponentRef<C>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoke this method to explicitly process change detection and its side-effects.
|
* Invoke this method to explicitly process change detection and its side-effects.
|
||||||
@ -491,7 +496,8 @@ export class ApplicationRef_ extends ApplicationRef {
|
|||||||
view.detachFromAppRef();
|
view.detachFromAppRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
bootstrap<C>(componentOrFactory: ComponentFactory<C>|Type<C>): ComponentRef<C> {
|
bootstrap<C>(componentOrFactory: ComponentFactory<C>|Type<C>, rootSelectorOrNode?: string|any):
|
||||||
|
ComponentRef<C> {
|
||||||
if (!this._initStatus.done) {
|
if (!this._initStatus.done) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Cannot bootstrap as there are still asynchronous initializers running. Bootstrap components in the `ngDoBootstrap` method of the root module.');
|
'Cannot bootstrap as there are still asynchronous initializers running. Bootstrap components in the `ngDoBootstrap` method of the root module.');
|
||||||
@ -509,7 +515,8 @@ export class ApplicationRef_ extends ApplicationRef {
|
|||||||
const ngModule = componentFactory instanceof ComponentFactoryBoundToModule ?
|
const ngModule = componentFactory instanceof ComponentFactoryBoundToModule ?
|
||||||
null :
|
null :
|
||||||
this._injector.get(NgModuleRef);
|
this._injector.get(NgModuleRef);
|
||||||
const compRef = componentFactory.create(Injector.NULL, [], componentFactory.selector, ngModule);
|
const selectorOrNode = rootSelectorOrNode || componentFactory.selector;
|
||||||
|
const compRef = componentFactory.create(Injector.NULL, [], selectorOrNode, ngModule);
|
||||||
|
|
||||||
compRef.onDestroy(() => { this._unloadComponent(compRef); });
|
compRef.onDestroy(() => { this._unloadComponent(compRef); });
|
||||||
const testability = compRef.injector.get(Testability, null);
|
const testability = compRef.injector.get(Testability, null);
|
||||||
|
@ -30,11 +30,11 @@ export function main() {
|
|||||||
|
|
||||||
beforeEach(() => { mockConsole = new MockConsole(); });
|
beforeEach(() => { mockConsole = new MockConsole(); });
|
||||||
|
|
||||||
function createRootEl() {
|
function createRootEl(selector = 'bootstrap-app') {
|
||||||
const doc = TestBed.get(DOCUMENT);
|
const doc = TestBed.get(DOCUMENT);
|
||||||
const rootEl = <HTMLElement>getDOM().firstChild(
|
const rootEl = <HTMLElement>getDOM().firstChild(
|
||||||
getDOM().content(getDOM().createTemplate(`<bootstrap-app></bootstrap-app>`)));
|
getDOM().content(getDOM().createTemplate(`<${selector}></${selector}>`)));
|
||||||
const oldRoots = getDOM().querySelectorAll(doc, 'bootstrap-app');
|
const oldRoots = getDOM().querySelectorAll(doc, selector);
|
||||||
for (let i = 0; i < oldRoots.length; i++) {
|
for (let i = 0; i < oldRoots.length; i++) {
|
||||||
getDOM().remove(oldRoots[i]);
|
getDOM().remove(oldRoots[i]);
|
||||||
}
|
}
|
||||||
@ -100,6 +100,34 @@ export function main() {
|
|||||||
expect(component.injector.get('hello')).toEqual('component');
|
expect(component.injector.get('hello')).toEqual('component');
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
it('should bootstrap a component with a custom selector',
|
||||||
|
async(inject([ApplicationRef, Compiler], (app: ApplicationRef, compiler: Compiler) => {
|
||||||
|
@Component({
|
||||||
|
selector: 'bootstrap-app',
|
||||||
|
template: '',
|
||||||
|
})
|
||||||
|
class SomeComponent {
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
providers: [{provide: 'hello', useValue: 'component'}],
|
||||||
|
declarations: [SomeComponent],
|
||||||
|
entryComponents: [SomeComponent],
|
||||||
|
})
|
||||||
|
class SomeModule {
|
||||||
|
}
|
||||||
|
|
||||||
|
createRootEl('custom-selector');
|
||||||
|
const modFactory = compiler.compileModuleSync(SomeModule);
|
||||||
|
const module = modFactory.create(TestBed);
|
||||||
|
const cmpFactory =
|
||||||
|
module.componentFactoryResolver.resolveComponentFactory(SomeComponent) !;
|
||||||
|
const component = app.bootstrap(cmpFactory, 'custom-selector');
|
||||||
|
|
||||||
|
// The component should see the child module providers
|
||||||
|
expect(component.injector.get('hello')).toEqual('component');
|
||||||
|
})));
|
||||||
|
|
||||||
describe('ApplicationRef', () => {
|
describe('ApplicationRef', () => {
|
||||||
beforeEach(() => { TestBed.configureTestingModule({imports: [createModule()]}); });
|
beforeEach(() => { TestBed.configureTestingModule({imports: [createModule()]}); });
|
||||||
|
|
||||||
|
2
tools/public_api_guard/core/core.d.ts
vendored
2
tools/public_api_guard/core/core.d.ts
vendored
@ -131,7 +131,7 @@ export declare abstract class ApplicationRef {
|
|||||||
readonly abstract isStable: Observable<boolean>;
|
readonly abstract isStable: Observable<boolean>;
|
||||||
readonly abstract viewCount: number;
|
readonly abstract viewCount: number;
|
||||||
abstract attachView(view: ViewRef): void;
|
abstract attachView(view: ViewRef): void;
|
||||||
abstract bootstrap<C>(componentFactory: ComponentFactory<C> | Type<C>): ComponentRef<C>;
|
abstract bootstrap<C>(componentFactory: ComponentFactory<C> | Type<C>, rootSelectorOrNode?: string | any): ComponentRef<C>;
|
||||||
abstract detachView(view: ViewRef): void;
|
abstract detachView(view: ViewRef): void;
|
||||||
abstract tick(): void;
|
abstract tick(): void;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user