From f3867597f079794ae9c7ed8be3788c9cea5123a3 Mon Sep 17 00:00:00 2001 From: hyperlife1119 Date: Fri, 7 Apr 2023 00:44:35 +0800 Subject: [PATCH] feat(common): add component input binding support for NgComponentOutlet (#49735) This commit add component input binding support for NgComponentOutlet. PR Close #49735 --- goldens/public-api/common/index.md | 8 +- .../src/directives/ng_component_outlet.ts | 121 +++++++++++++++--- .../directives/ng_component_outlet_spec.ts | 110 +++++++++++++++- .../common/ngComponentOutlet/ts/module.ts | 10 +- 4 files changed, 222 insertions(+), 27 deletions(-) diff --git a/goldens/public-api/common/index.md b/goldens/public-api/common/index.md index 9292ea537028a..ca2367a5e1ac4 100644 --- a/goldens/public-api/common/index.md +++ b/goldens/public-api/common/index.md @@ -491,7 +491,7 @@ export class NgClass implements DoCheck { } // @public -export class NgComponentOutlet implements OnChanges, OnDestroy { +export class NgComponentOutlet implements OnChanges, DoCheck, OnDestroy { constructor(_viewContainerRef: ViewContainerRef); // (undocumented) ngComponentOutlet: Type | null; @@ -500,15 +500,19 @@ export class NgComponentOutlet implements OnChanges, OnDestroy { // (undocumented) ngComponentOutletInjector?: Injector; // (undocumented) + ngComponentOutletInputs?: Record; + // (undocumented) ngComponentOutletNgModule?: Type; // @deprecated (undocumented) ngComponentOutletNgModuleFactory?: NgModuleFactory; // (undocumented) + ngDoCheck(): void; + // (undocumented) ngOnChanges(changes: SimpleChanges): void; // (undocumented) ngOnDestroy(): void; // (undocumented) - static ɵdir: i0.ɵɵDirectiveDeclaration; + static ɵdir: i0.ɵɵDirectiveDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } diff --git a/packages/common/src/directives/ng_component_outlet.ts b/packages/common/src/directives/ng_component_outlet.ts index 2c6f466957920..59787a5ae6053 100644 --- a/packages/common/src/directives/ng_component_outlet.ts +++ b/packages/common/src/directives/ng_component_outlet.ts @@ -6,8 +6,18 @@ * found in the LICENSE file at https://angular.io/license */ -import {ComponentRef, createNgModule, Directive, Injector, Input, NgModuleFactory, NgModuleRef, OnChanges, OnDestroy, SimpleChanges, Type, ViewContainerRef} from '@angular/core'; +import {ComponentRef, createNgModule, Directive, DoCheck, Injector, Input, NgModuleFactory, NgModuleRef, OnChanges, OnDestroy, SimpleChanges, Type, ViewContainerRef} from '@angular/core'; +/** + * Represents internal object used to track state of each component input. + */ +interface ComponentInputState { + /** + * Track whether the input exists in the current object bound to the component input; + * inputs that are not present any more can be removed from the internal data structures. + */ + touched: boolean; +} /** * Instantiates a {@link Component} type and inserts its Host View into the current View. @@ -22,6 +32,9 @@ import {ComponentRef, createNgModule, Directive, Injector, Input, NgModuleFactor * * You can control the component creation process by using the following optional attributes: * + * * `ngComponentOutletInputs`: Optional component inputs object, which will be bind to the + * component. + * * * `ngComponentOutletInjector`: Optional custom {@link Injector} that will be used as parent for * the Component. Defaults to the injector of the current view container. * @@ -42,6 +55,13 @@ import {ComponentRef, createNgModule, Directive, Injector, Input, NgModuleFactor * * ``` * + * With inputs + * ``` + * + * + * ``` + * * Customized injector/content * ``` * ` +}) +class TestInputsComponent { + currentComponent: Type|null = null; + inputs?: Record; +} diff --git a/packages/examples/common/ngComponentOutlet/ts/module.ts b/packages/examples/common/ngComponentOutlet/ts/module.ts index 99684f4cb940a..276630e5f99f1 100644 --- a/packages/examples/common/ngComponentOutlet/ts/module.ts +++ b/packages/examples/common/ngComponentOutlet/ts/module.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Component, Injectable, Injector, NgModule, OnInit, TemplateRef, ViewChild, ViewContainerRef} from '@angular/core'; +import {Component, Injectable, Injector, Input, NgModule, OnInit, TemplateRef, ViewChild, ViewContainerRef} from '@angular/core'; import {BrowserModule} from '@angular/platform-browser'; @@ -33,9 +33,11 @@ export class Greeter { @Component({ selector: 'complete-component', - template: `Complete: {{ greeter.suffix }}` + template: `{{ label }}: {{ greeter.suffix }}` }) export class CompleteComponent { + @Input() label!: string; + constructor(public greeter: Greeter) {} } @@ -45,12 +47,16 @@ export class CompleteComponent { Ahoj Svet ` }) export class NgComponentOutletCompleteExample implements OnInit { // This field is necessary to expose CompleteComponent to the template. CompleteComponent = CompleteComponent; + + myInputs = {'label': 'Complete'}; + myInjector: Injector; @ViewChild('ahoj', {static: true}) ahojTemplateRef!: TemplateRef; @ViewChild('svet', {static: true}) svetTemplateRef!: TemplateRef;