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
|
||||
* 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 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.
|
||||
|
@ -491,7 +496,8 @@ export class ApplicationRef_ extends ApplicationRef {
|
|||
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) {
|
||||
throw new Error(
|
||||
'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 ?
|
||||
null :
|
||||
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); });
|
||||
const testability = compRef.injector.get(Testability, null);
|
||||
|
|
|
@ -30,11 +30,11 @@ export function main() {
|
|||
|
||||
beforeEach(() => { mockConsole = new MockConsole(); });
|
||||
|
||||
function createRootEl() {
|
||||
function createRootEl(selector = 'bootstrap-app') {
|
||||
const doc = TestBed.get(DOCUMENT);
|
||||
const rootEl = <HTMLElement>getDOM().firstChild(
|
||||
getDOM().content(getDOM().createTemplate(`<bootstrap-app></bootstrap-app>`)));
|
||||
const oldRoots = getDOM().querySelectorAll(doc, 'bootstrap-app');
|
||||
getDOM().content(getDOM().createTemplate(`<${selector}></${selector}>`)));
|
||||
const oldRoots = getDOM().querySelectorAll(doc, selector);
|
||||
for (let i = 0; i < oldRoots.length; i++) {
|
||||
getDOM().remove(oldRoots[i]);
|
||||
}
|
||||
|
@ -100,6 +100,34 @@ export function main() {
|
|||
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', () => {
|
||||
beforeEach(() => { TestBed.configureTestingModule({imports: [createModule()]}); });
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ export declare abstract class ApplicationRef {
|
|||
readonly abstract isStable: Observable<boolean>;
|
||||
readonly abstract viewCount: number;
|
||||
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 tick(): void;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue