Revert "refactor(core): remove ComponentFactoryResolver & ComponentFa… · angular/angular@ecae525 · GitHub
Skip to content

Commit ecae525

Browse files
committed
Revert "refactor(core): remove ComponentFactoryResolver & ComponentFactory from the api surface"
This reverts commit 9d76ac8. g3 cleanup not complete
1 parent 4a174b8 commit ecae525

21 files changed

Lines changed: 364 additions & 95 deletions

goldens/public-api/core/index.api.md

Lines changed: 29 additions & 0 deletions

packages/core/src/application/application_ref.ts

Lines changed: 66 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ import '../util/ng_hmr_mode';
1010
import '../util/ng_jit_mode';
1111
import '../util/ng_server_mode';
1212

13-
import {type Observable, Subject, type Subscription} from 'rxjs';
14-
import {map} from 'rxjs/operators';
1513
import {
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

2121
import {ZONELESS_ENABLED} from '../change_detection/scheduling/zoneless_scheduling';
2222
import {Console} from '../console';
@@ -25,8 +25,8 @@ import {Injectable} from '../di/injectable';
2525
import {InjectionToken} from '../di/injection_token';
2626
import {Injector} from '../di/injector';
2727
import {EnvironmentInjector, type R3Injector} from '../di/r3_injector';
28-
import {INTERNAL_APPLICATION_ERROR_HANDLER} from '../error_handler';
2928
import {formatRuntimeError, RuntimeError, RuntimeErrorCode} from '../errors';
29+
import {INTERNAL_APPLICATION_ERROR_HANDLER} from '../error_handler';
3030
import {Type} from '../interface/type';
3131
import {ComponentFactory, ComponentRef} from '../linker/component_factory';
3232
import {ComponentFactoryResolver} from '../linker/component_factory_resolver';
@@ -44,10 +44,10 @@ import {ViewRef as InternalViewRef} from '../render3/view_ref';
4444
import {TESTABILITY} from '../testability/testability';
4545
import {NgZone} from '../zone/ng_zone';
4646

47-
import {ProfilerEvent} from '../../primitives/devtools';
4847
import {profiler} from '../render3/profiler';
49-
import {isReactiveLViewConsumer} from '../render3/reactive_lview_consumer';
48+
import {ProfilerEvent} from '../../primitives/devtools';
5049
import {EffectScheduler} from '../render3/reactivity/root_effect_scheduler';
50+
import {isReactiveLViewConsumer} from '../render3/reactive_lview_consumer';
5151
import {ApplicationInitStatus} from './application_init';
5252
import {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

packages/core/src/linker.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ export {
1414
CompilerOptions,
1515
ModuleWithComponentFactories,
1616
} from './linker/compiler';
17-
export {ComponentRef, ComponentFactory as ɵComponentFactory} from './linker/component_factory';
18-
export {ComponentFactoryResolver as ɵComponentFactoryResolver} from './linker/component_factory_resolver';
17+
export {ComponentFactory, ComponentRef} from './linker/component_factory';
18+
export {ComponentFactoryResolver} from './linker/component_factory_resolver';
1919
export {DestroyRef} from './linker/destroy_ref';
2020
export {ElementRef} from './linker/element_ref';
2121
export {NgModuleFactory, NgModuleRef} from './linker/ng_module_factory';

packages/core/src/linker/component_factory.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ export abstract class ComponentRef<C> {
8585
* Base class for a factory that can create a component dynamically.
8686
* Instantiate a factory for a given type of component with `resolveComponentFactory()`.
8787
* Use the resulting `ComponentFactory.create()` method to create a component of that type.
88+
*
89+
* @publicApi
90+
*
91+
* @deprecated Angular no longer requires Component factories. Please use other APIs where
92+
* Component class can be used directly.
8893
*/
8994
export abstract class ComponentFactory<C> {
9095
/**

packages/core/src/linker/component_factory_resolver.ts

Lines changed: 5 additions & 0 deletions

0 commit comments

Comments
 (0)