Skip to content

Commit

Permalink
chore: stabilize experimental API
Browse files Browse the repository at this point in the history
  • Loading branch information
gund committed Jan 7, 2025
1 parent 48f4d71 commit b517521
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 40 deletions.
2 changes: 1 addition & 1 deletion goldens/ng-dynamic-component/api-signal-component-io.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import * as i0 from '@angular/core';

// @public (undocumented)
// @public
export class SignalComponentIoModule {
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<SignalComponentIoModule, never>;
Expand Down
8 changes: 1 addition & 7 deletions projects/ng-dynamic-component/signal-component-io/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,11 @@ This package enables signal based inputs/outputs support for dynamically rendere
This package requires Angular version which supports signals.
Please refer to (Angular docs)[https://angular.dev/] to see which minimal version is required.

## Warning: Experimental

This package is still **experimental** and not ready for producation!
APIs may change in the future or be removed completely and never make it to stable release!
Only use it to evaluate the features and provide feedback.

## Usage

**Since v10.8.0**

Import `SignalComponentIoModule` in your application module or config:
Import `SignalComponentIoModule` in your application root module or config:

```ts
import { NgModule } from '@angular/core';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { ComponentIO } from 'ng-dynamic-component';
import { SignalComponentIO } from './signal-component-io';

/**
* Enables signal based inputs/outputs support for dynamically rendered components.
* Import once at the root of your application.
* @public
* @experimental
*/
@NgModule({
providers: [{ provide: ComponentIO, useClass: SignalComponentIO }],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ import { outputToObservable } from '@angular/core/rxjs-interop';
import { ComponentIO, ComponentInputKey } from 'ng-dynamic-component';
import { Observable, isObservable } from 'rxjs';

/**
* @internal
* @experimental
*/
/** @internal */
@Injectable()
export class SignalComponentIO implements ComponentIO {
setInput<T, K extends ComponentInputKey<T>>(
Expand Down
54 changes: 27 additions & 27 deletions projects/ng-dynamic-component/src/lib/io/io.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import {
StaticProvider,
Type,
} from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { merge, Subject } from 'rxjs';
import { takeUntil, tap } from 'rxjs/operators';

import {
DynamicComponentInjector,
Expand Down Expand Up @@ -69,7 +69,6 @@ export class IoService implements OnDestroy {

private inputs: InputsType = {};
private outputs: OutputsType = {};
private outputsChanged: (outputs: OutputsType) => boolean = () => false;

private get compRef() {
return this.compInjector.componentRef as ComponentRef<AnyComponent> | null;
Expand Down Expand Up @@ -103,6 +102,7 @@ export class IoService implements OnDestroy {
}
}

/** @internal */
ngOnDestroy(): void {
this.disconnectOutputs();
}
Expand All @@ -112,7 +112,7 @@ export class IoService implements OnDestroy {
*
* It will detect both new and mutated changes.
*/
update(inputs?: InputsType | null, outputs?: OutputsType | null) {
update(inputs?: InputsType | null, outputs?: OutputsType | null): void {
if (!this.compRef) {
this.disconnectOutputs();
return;
Expand All @@ -138,6 +138,10 @@ export class IoService implements OnDestroy {
}
}

private outputsChanged(outputs: OutputsType) {
return false;
}

private isComponentInstChanged(): boolean {
if (this.lastComponentInst !== this.componentInst) {
this.lastComponentInst = this.componentInst;
Expand Down Expand Up @@ -193,25 +197,24 @@ export class IoService implements OnDestroy {
this.disconnectOutputs();

const compRef = this.compRef;
let outputs = this.outputs;
const outputs = this.outputs;

if (!outputs || !compRef) {
return;
}

outputs = this.resolveOutputs(outputs);

const resolvedOutputs = this.resolveOutputs(outputs);
const componentIO = this.componentIO;

for (const name of Object.keys(outputs)) {
componentIO
.getOutput(compRef, name)
.pipe(takeUntil(this.outputsShouldDisconnect$))
.subscribe((event) => {
this.cdr.markForCheck();
return (outputs[name] as EventHandler)(event);
});
}
merge(
...Object.keys(resolvedOutputs).map((name) =>
componentIO
.getOutput(compRef, name)
.pipe(tap((event) => resolvedOutputs[name](event))),
),
)
.pipe(takeUntil(this.outputsShouldDisconnect$))
.subscribe(() => this.cdr.markForCheck());
}

private disconnectOutputs() {
Expand Down Expand Up @@ -240,7 +243,7 @@ export class IoService implements OnDestroy {
// TODO: Replace ComponentFactory once new API is created
// @see https://github.com/angular/angular/issues/44926
// eslint-disable-next-line deprecation/deprecation
private resolveCompFactory(): ComponentFactory<AnyComponent> | undefined {
private resolveCompFactory() {
if (!this.compRef) {
return;
}
Expand All @@ -264,16 +267,16 @@ export class IoService implements OnDestroy {
this.compFactory = this.resolveCompFactory();
}

private resolveOutputs(outputs: OutputsType): OutputsType {
private resolveOutputs(outputs: OutputsType) {
this.updateOutputsEventContext();

outputs = this.processOutputs(outputs);
const processedOutputs = this.processOutputs(outputs);

if (!this.compFactory) {
return outputs;
return processedOutputs;
}

return this.remapIO(outputs, this.compFactory.outputs);
return this.remapIO(processedOutputs, this.compFactory.outputs);
}

private updateOutputsEventContext() {
Expand All @@ -292,7 +295,7 @@ export class IoService implements OnDestroy {
}
}

private processOutputs(outputs: OutputsType): OutputsTypeProcessed {
private processOutputs(outputs: OutputsType) {
const processedOutputs: OutputsTypeProcessed = {};

Object.keys(outputs).forEach((key) => {
Expand Down Expand Up @@ -339,7 +342,7 @@ export class IoService implements OnDestroy {
private remapIO<T extends Record<string, unknown>>(
io: T,
mapping: IOMappingList,
): T {
) {
const newIO: Record<string, unknown> = {};

Object.keys(io).forEach((key) => {
Expand All @@ -350,10 +353,7 @@ export class IoService implements OnDestroy {
return newIO as T;
}

private findPropByTplInMapping(
tplName: string,
mapping: IOMappingList,
): string | null {
private findPropByTplInMapping(tplName: string, mapping: IOMappingList) {
for (const map of mapping) {
if (map.templateName === tplName) {
return map.propName;
Expand Down

0 comments on commit b517521

Please sign in to comment.