@@ -10,13 +10,13 @@ import '../util/ng_hmr_mode';
1010import '../util/ng_jit_mode' ;
1111import '../util/ng_server_mode' ;
1212
13- import { type Observable , Subject , type Subscription } from 'rxjs' ;
14- import { map } from 'rxjs/operators' ;
1513import {
16- getActiveConsumer ,
1714 setActiveConsumer ,
15+ getActiveConsumer ,
1816 setThrowInvalidWriteToSignalError ,
1917} from '../../primitives/signals' ;
18+ import { type Observable , Subject , type Subscription } from 'rxjs' ;
19+ import { map } from 'rxjs/operators' ;
2020
2121import { ZONELESS_ENABLED } from '../change_detection/scheduling/zoneless_scheduling' ;
2222import { Console } from '../console' ;
@@ -25,8 +25,8 @@ import {Injectable} from '../di/injectable';
2525import { InjectionToken } from '../di/injection_token' ;
2626import { Injector } from '../di/injector' ;
2727import { EnvironmentInjector , type R3Injector } from '../di/r3_injector' ;
28- import { INTERNAL_APPLICATION_ERROR_HANDLER } from '../error_handler' ;
2928import { formatRuntimeError , RuntimeError , RuntimeErrorCode } from '../errors' ;
29+ import { INTERNAL_APPLICATION_ERROR_HANDLER } from '../error_handler' ;
3030import { Type } from '../interface/type' ;
3131import { ComponentFactory , ComponentRef } from '../linker/component_factory' ;
3232import { ComponentFactoryResolver } from '../linker/component_factory_resolver' ;
@@ -44,10 +44,10 @@ import {ViewRef as InternalViewRef} from '../render3/view_ref';
4444import { TESTABILITY } from '../testability/testability' ;
4545import { NgZone } from '../zone/ng_zone' ;
4646
47- import { ProfilerEvent } from '../../primitives/devtools' ;
4847import { profiler } from '../render3/profiler' ;
49- import { isReactiveLViewConsumer } from '../render3/reactive_lview_consumer ' ;
48+ import { ProfilerEvent } from '../../primitives/devtools ' ;
5049import { EffectScheduler } from '../render3/reactivity/root_effect_scheduler' ;
50+ import { isReactiveLViewConsumer } from '../render3/reactive_lview_consumer' ;
5151import { ApplicationInitStatus } from './application_init' ;
5252import { TracingAction , TracingService , TracingSnapshot } from './tracing' ;
5353
@@ -441,13 +441,61 @@ export class ApplicationRef {
441441 * While in this example, we are providing reference to a DOM node.
442442 *
443443 * {@example core/ts/platform/platform.ts region='domNode'}
444+ *
445+ * @deprecated Passing Component factories as the `Application.bootstrap` function argument is
446+ * deprecated. Pass Component Types instead.
444447 */
445- bootstrap < C > ( component : Type < C > , rootSelectorOrNode ?: string | any ) : ComponentRef < C > {
446- return this . bootstrapImpl ( component , rootSelectorOrNode ) ;
448+ bootstrap < C > (
449+ componentFactory : ComponentFactory < C > ,
450+ rootSelectorOrNode ?: string | any ,
451+ ) : ComponentRef < C > ;
452+
453+ /**
454+ * Bootstrap a component onto the element identified by its selector or, optionally, to a
455+ * specified element.
456+ *
457+ * @usageNotes
458+ * ### Bootstrap process
459+ *
460+ * When bootstrapping a component, Angular mounts it onto a target DOM element
461+ * and kicks off automatic change detection. The target DOM element can be
462+ * provided using the `rootSelectorOrNode` argument.
463+ *
464+ * If the target DOM element is not provided, Angular tries to find one on a page
465+ * using the `selector` of the component that is being bootstrapped
466+ * (first matched element is used).
467+ *
468+ * ### Example
469+ *
470+ * Generally, we define the component to bootstrap in the `bootstrap` array of `NgModule`,
471+ * but it requires us to know the component while writing the application code.
472+ *
473+ * Imagine a situation where we have to wait for an API call to decide about the component to
474+ * bootstrap. We can use the `ngDoBootstrap` hook of the `NgModule` and call this method to
475+ * dynamically bootstrap a component.
476+ *
477+ * {@example core/ts/platform/platform.ts region='componentSelector'}
478+ *
479+ * Optionally, a component can be mounted onto a DOM element that does not match the
480+ * selector of the bootstrapped component.
481+ *
482+ * In the following example, we are providing a CSS selector to match the target element.
483+ *
484+ * {@example core/ts/platform/platform.ts region='cssSelector'}
485+ *
486+ * While in this example, we are providing reference to a DOM node.
487+ *
488+ * {@example core/ts/platform/platform.ts region='domNode'}
489+ */
490+ bootstrap < C > (
491+ componentOrFactory : ComponentFactory < C > | Type < C > ,
492+ rootSelectorOrNode ?: string | any ,
493+ ) : ComponentRef < C > {
494+ return this . bootstrapImpl ( componentOrFactory , rootSelectorOrNode ) ;
447495 }
448496
449497 private bootstrapImpl < C > (
450- component : Type < C > ,
498+ componentOrFactory : ComponentFactory < C > | Type < C > ,
451499 rootSelectorOrNode ?: string | any ,
452500 injector : Injector = Injector . NULL ,
453501 ) : ComponentRef < C > {
@@ -456,12 +504,13 @@ export class ApplicationRef {
456504 profiler ( ProfilerEvent . BootstrapComponentStart ) ;
457505
458506 ( typeof ngDevMode === 'undefined' || ngDevMode ) && warnIfDestroyed ( this . _destroyed ) ;
507+ const isComponentFactory = componentOrFactory instanceof ComponentFactory ;
459508 const initStatus = this . _injector . get ( ApplicationInitStatus ) ;
460509
461510 if ( ! initStatus . done ) {
462511 let errorMessage = '' ;
463512 if ( typeof ngDevMode === 'undefined' || ngDevMode ) {
464- const standalone = isStandalone ( component ) ;
513+ const standalone = ! isComponentFactory && isStandalone ( componentOrFactory ) ;
465514 errorMessage =
466515 'Cannot bootstrap as there are still asynchronous initializers running.' +
467516 ( standalone
@@ -471,8 +520,13 @@ export class ApplicationRef {
471520 throw new RuntimeError ( RuntimeErrorCode . ASYNC_INITIALIZERS_STILL_RUNNING , errorMessage ) ;
472521 }
473522
474- const resolver = this . _injector . get ( ComponentFactoryResolver ) ;
475- const componentFactory = resolver . resolveComponentFactory ( component ) ! ;
523+ let componentFactory : ComponentFactory < C > ;
524+ if ( isComponentFactory ) {
525+ componentFactory = componentOrFactory ;
526+ } else {
527+ const resolver = this . _injector . get ( ComponentFactoryResolver ) ;
528+ componentFactory = resolver . resolveComponentFactory ( componentOrFactory ) ! ;
529+ }
476530 this . componentTypes . push ( componentFactory . componentType ) ;
477531
478532 // Create a factory associated with the current module if it's not bound to some other
0 commit comments