/
githubmirror
/
angular
Обзор
Документация
Войти
/
githubmirror
/
angular
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
packages/core/src/render3/component.ts
224 строки
8 KB
SkyZeroZx
docs: Adds links to relevant guides for APIs in core package
17 ноя 2025, 19:47
17 ноя 2025, 19:47
0432e76
Код
Авторство
О чём код?
/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.dev/license */ import {Injector} from '../di/injector'; import {EnvironmentInjector, getNullInjector} from '../di/r3_injector'; import {Type} from '../interface/type'; import {ComponentRef} from '../linker/component_factory'; import {ComponentFactory} from './component_ref'; import {getComponentDef} from './def_getters'; import {Binding, DirectiveWithBindings} from './dynamic_bindings'; import {assertComponentDef} from './errors'; /** * Creates a `ComponentRef` instance based on provided component type and a set of options. * * @usageNotes * * The example below demonstrates how the `createComponent` function can be used * to create an instance of a ComponentRef dynamically and attach it to an ApplicationRef, * so that it gets included into change detection cycles. * * Note: the example uses standalone components, but the function can also be used for * non-standalone components (declared in an NgModule) as well. * * ```angular-ts * @Component({ * template: `Hello {{ name }}!` * }) * class HelloComponent { * name = 'Angular'; * } * * @Component({ * template: `<div id="hello-component-host"></div>` * }) * class RootComponent {} * * // Bootstrap an application. * const applicationRef = await bootstrapApplication(RootComponent); * * // Locate a DOM node that would be used as a host. * const hostElement = document.getElementById('hello-component-host'); * * // Get an `EnvironmentInjector` instance from the `ApplicationRef`. * const environmentInjector = applicationRef.injector; * * // We can now create a `ComponentRef` instance. * const componentRef = createComponent(HelloComponent, {hostElement, environmentInjector}); * * // Last step is to register the newly created ref using the `ApplicationRef` instance * // to include the component view into change detection cycles. * applicationRef.attachView(componentRef.hostView); * componentRef.changeDetectorRef.detectChanges(); * ``` * * @param component Component class reference. * @param options Set of options to use: * * `environmentInjector`: An `EnvironmentInjector` instance to be used for the component. * * `hostElement` (optional): A DOM node that should act as a host node for the component. If not * provided, Angular creates one based on the tag name used in the component selector (and falls * back to using `div` if selector doesn't have tag name info). * * `elementInjector` (optional): An `ElementInjector` instance, see additional info about it * [here](guide/di/hierarchical-dependency-injection#elementinjector). * * `projectableNodes` (optional): A list of DOM nodes that should be projected through * [`<ng-content>`](api/core/ng-content) of the new component instance, e.g., * `[[element1, element2]]`: projects `element1` and `element2` into the same `<ng-content>`. * `[[element1, element2], [element3]]`: projects `element1` and `element2` into one `<ng-content>`, * and `element3` into a separate `<ng-content>`. * * `directives` (optional): Directives that should be applied to the component. * * `bindings` (optional): Bindings to apply to the root component. * @returns ComponentRef instance that represents a given Component. * * @see [Host view using `ViewContainerRef.createComponent`](guide/components/programmatic-rendering#host-view-using-viewcontainerrefcreatecomponent) * @see [Popup attached to `document.body` with `createComponent` + `hostElement`](guide/components/programmatic-rendering#popup-attached-to-documentbody-with-createcomponent--hostelement) * * @publicApi */ export function createComponent<C>( component: Type<C>, options: { environmentInjector: EnvironmentInjector; hostElement?: Element; elementInjector?: Injector; projectableNodes?: Node[][]; directives?: (Type<unknown> | DirectiveWithBindings<unknown>)[]; bindings?: Binding[]; }, ): ComponentRef<C> { ngDevMode && assertComponentDef(component); const componentDef = getComponentDef(component)!; const elementInjector = options.elementInjector || getNullInjector(); const factory = new ComponentFactory<C>(componentDef); return factory.create( elementInjector, options.projectableNodes, options.hostElement, options.environmentInjector, options.directives, options.bindings, ); } /** * An interface that describes the subset of component metadata * that can be retrieved using the `reflectComponentType` function. * * @publicApi */ export interface ComponentMirror<C> { /** * The component's HTML selector. */ get selector(): string; /** * The type of component the factory will create. */ get type(): Type<C>; /** * The inputs of the component. */ get inputs(): ReadonlyArray<{ readonly propName: string; readonly templateName: string; readonly transform?: (value: any) => any; readonly isSignal: boolean; }>; /** * The outputs of the component. */ get outputs(): ReadonlyArray<{readonly propName: string; readonly templateName: string}>; /** * Selector for all <ng-content> elements in the component. */ get ngContentSelectors(): ReadonlyArray<string>; /** * Whether this component is marked as standalone. * Note: an extra flag, not present in `ComponentFactory`. */ get isStandalone(): boolean; /** * // TODO(signals): Remove internal and add public documentation * @internal */ get isSignal(): boolean; } /** * Creates an object that allows to retrieve component metadata. * * @usageNotes * * The example below demonstrates how to use the function and how the fields * of the returned object map to the component metadata. * * ```angular-ts * @Component({ * selector: 'foo-component', * template: ` * <ng-content></ng-content> * <ng-content select="content-selector-a"></ng-content> * `, * }) * class FooComponent { * @Input('inputName') inputPropName: string; * @Output('outputName') outputPropName = new EventEmitter<void>(); * } * * const mirror = reflectComponentType(FooComponent); * expect(mirror.type).toBe(FooComponent); * expect(mirror.selector).toBe('foo-component'); * expect(mirror.isStandalone).toBe(true); * expect(mirror.inputs).toEqual([{propName: 'inputName', templateName: 'inputPropName'}]); * expect(mirror.outputs).toEqual([{propName: 'outputName', templateName: 'outputPropName'}]); * expect(mirror.ngContentSelectors).toEqual([ * '*', // first `<ng-content>` in a template, the selector defaults to `*` * 'content-selector-a' // second `<ng-content>` in a template * ]); * ``` * * @param component Component class reference. * @returns An object that allows to retrieve component metadata. * * @publicApi */ export function reflectComponentType<C>(component: Type<C>): ComponentMirror<C> | null { const componentDef = getComponentDef(component); if (!componentDef) return null; const factory = new ComponentFactory<C>(componentDef); return { get selector(): string { return factory.selector; }, get type(): Type<C> { return factory.componentType; }, get inputs(): ReadonlyArray<{ propName: string; templateName: string; transform?: (value: any) => any; isSignal: boolean; }> { return factory.inputs; }, get outputs(): ReadonlyArray<{propName: string; templateName: string}> { return factory.outputs; }, get ngContentSelectors(): ReadonlyArray<string> { return factory.ngContentSelectors; }, get isStandalone(): boolean { return componentDef.standalone; }, get isSignal(): boolean { return componentDef.signals; }, }; }