0
# ng-dynamic-component
1
2
ng-dynamic-component is a comprehensive Angular TypeScript library that provides utilities for dynamically creating and managing Angular components, directives, and their inputs/outputs at runtime. It enables developers to create flexible, data-driven user interfaces by allowing components to be selected and rendered programmatically while maintaining Angular's standard component lifecycle hooks, change detection, and event handling.
3
4
## Package Information
5
6
- **Package Name**: ng-dynamic-component
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install ng-dynamic-component`
10
- **Peer Dependencies**: @angular/common >=14.1.3, @angular/core >=14.1.3, rxjs >=6.0.0
11
12
## Core Imports
13
14
```typescript
15
import { DynamicComponent, DynamicModule } from "ng-dynamic-component";
16
```
17
18
For importing specific functionality:
19
20
```typescript
21
import {
22
DynamicComponent,
23
DynamicIoDirective,
24
ComponentOutletIoDirective,
25
DynamicAttributesDirective,
26
InputsType,
27
OutputsType
28
} from "ng-dynamic-component";
29
```
30
31
## Basic Usage
32
33
### Creating Dynamic Components
34
35
```typescript
36
import { Component, Type } from '@angular/core';
37
import { DynamicComponent } from 'ng-dynamic-component';
38
39
@Component({
40
selector: 'app-example',
41
template: `
42
<ndc-dynamic
43
[ndcDynamicComponent]="selectedComponent"
44
[ndcDynamicInputs]="componentInputs"
45
[ndcDynamicOutputs]="componentOutputs"
46
(ndcDynamicCreated)="onComponentCreated($event)">
47
</ndc-dynamic>
48
`
49
})
50
export class ExampleComponent {
51
selectedComponent: Type<any> = MyDynamicComponent;
52
componentInputs = { title: 'Hello World', data: [1, 2, 3] };
53
componentOutputs = {
54
onSave: (event: any) => console.log('Saved:', event),
55
onCancel: () => console.log('Cancelled')
56
};
57
58
onComponentCreated(componentRef: ComponentRef<any>) {
59
console.log('Dynamic component created:', componentRef);
60
}
61
}
62
```
63
64
### Using with NgComponentOutlet
65
66
```typescript
67
import { ComponentOutletIoDirective } from 'ng-dynamic-component';
68
69
@Component({
70
template: `
71
<ng-container
72
*ngComponentOutlet="selectedComponent"
73
[ngComponentOutletNdcDynamicInputs]="inputs"
74
[ngComponentOutletNdcDynamicOutputs]="outputs">
75
</ng-container>
76
`
77
})
78
export class OutletExampleComponent {
79
selectedComponent = MyComponent;
80
inputs = { message: 'Hello' };
81
outputs = { onClick: (data: any) => this.handleClick(data) };
82
}
83
```
84
85
## Architecture
86
87
ng-dynamic-component is built around several key architectural components:
88
89
- **Core Dynamic Component**: `DynamicComponent` provides the main interface for creating components at runtime
90
- **IO System**: Comprehensive input/output binding system with `DynamicIoDirective` and related services
91
- **Outlet Enhancement**: Extensions for Angular's built-in `NgComponentOutlet` with additional capabilities
92
- **Attribute Management**: Dynamic HTML attribute binding through `DynamicAttributesDirective`
93
- **Directive Injection**: Experimental dynamic directive attachment system
94
- **Type Safety**: Full TypeScript integration with generic types and comprehensive interfaces
95
- **Modular Design**: Ten specialized modules for different use cases and integration patterns
96
97
## Capabilities
98
99
### Dynamic Component Creation
100
101
Core functionality for creating Angular components dynamically at runtime with full lifecycle support, custom injectors, and projected content.
102
103
```typescript { .api }
104
@Component({
105
selector: 'ndc-dynamic',
106
standalone: true,
107
template: ''
108
})
109
export class DynamicComponent<C = unknown> implements OnChanges, DynamicComponentInjector {
110
@Input() ndcDynamicComponent?: Type<C> | null;
111
@Input() ndcDynamicInjector?: Injector | null;
112
@Input() ndcDynamicProviders?: StaticProvider[] | null;
113
@Input() ndcDynamicContent?: Node[][];
114
@Input() ndcDynamicNgModuleRef?: NgModuleRef<unknown>;
115
@Input() ndcDynamicEnvironmentInjector?: EnvironmentInjector | NgModuleRef<unknown>;
116
@Output() ndcDynamicCreated: EventEmitter<ComponentRef<C>>;
117
118
componentRef: ComponentRef<C> | null;
119
createDynamicComponent(): void;
120
}
121
```
122
123
[Dynamic Component Creation](./dynamic-component.md)
124
125
### Dynamic Input/Output Management
126
127
Type-safe system for binding inputs and outputs to dynamic components at runtime, supporting both function handlers and complex output expressions.
128
129
```typescript { .api }
130
interface InputsType {
131
[k: string]: unknown;
132
}
133
134
interface OutputsType {
135
[k: string]: OutputExpression | undefined;
136
}
137
138
type OutputExpression = EventHandler | OutputWithArgs;
139
type EventHandler<T = unknown> = (event: T) => unknown;
140
141
interface OutputWithArgs {
142
handler: AnyFunction;
143
args?: unknown[];
144
}
145
```
146
147
[Input/Output Management](./input-output.md)
148
149
### NgComponentOutlet Enhancement
150
151
Directives that extend Angular's built-in NgComponentOutlet with dynamic input/output binding and component reference access.
152
153
```typescript { .api }
154
@Directive({
155
selector: '[ngComponentOutlet]',
156
standalone: true,
157
exportAs: 'ndcComponentOutletInjector'
158
})
159
export class ComponentOutletInjectorDirective {
160
readonly componentRef: ComponentRef<unknown>;
161
}
162
163
@Directive({
164
selector: '[ngComponentOutletNdcDynamicInputs],[ngComponentOutletNdcDynamicOutputs]',
165
standalone: true,
166
exportAs: 'ndcDynamicIo'
167
})
168
export class ComponentOutletIoDirective implements DoCheck {
169
@Input() ngComponentOutletNdcDynamicInputs?: InputsType | null;
170
@Input() ngComponentOutletNdcDynamicOutputs?: OutputsType | null;
171
}
172
```
173
174
[NgComponentOutlet Enhancement](./component-outlet.md)
175
176
### Dynamic Attributes Management
177
178
System for dynamically setting and managing HTML attributes on component elements at runtime.
179
180
```typescript { .api }
181
interface AttributesMap {
182
[key: string]: string;
183
}
184
185
@Directive({
186
selector: '[ndcDynamicAttributes],[ngComponentOutletNdcDynamicAttributes]',
187
standalone: true,
188
exportAs: 'ndcDynamicAttributes'
189
})
190
export class DynamicAttributesDirective implements DoCheck {
191
@Input() ndcDynamicAttributes?: AttributesMap | null;
192
@Input() ngComponentOutletNdcDynamicAttributes?: AttributesMap | null;
193
194
setAttribute(name: string, value: string, namespace?: string): void;
195
removeAttribute(name: string, namespace?: string): void;
196
}
197
```
198
199
[Dynamic Attributes](./dynamic-attributes.md)
200
201
### Dynamic Directive Injection (Experimental)
202
203
Advanced system for dynamically attaching directives to components at runtime with input/output binding support.
204
205
```typescript { .api }
206
interface DynamicDirectiveDef<T> {
207
type: Type<T>;
208
inputs?: InputsType;
209
outputs?: OutputsType;
210
}
211
212
function dynamicDirectiveDef<T>(
213
type: Type<T>,
214
inputs?: InputsType,
215
outputs?: OutputsType
216
): DynamicDirectiveDef<T>;
217
218
interface DirectiveRef<T> {
219
instance: T;
220
type: Type<T>;
221
injector: Injector;
222
hostComponent: unknown;
223
hostView: ViewRef;
224
location: ElementRef;
225
changeDetectorRef: ChangeDetectorRef;
226
onDestroy: (callback: Function) => void;
227
}
228
```
229
230
[Dynamic Directive Injection](./dynamic-directives.md)
231
232
### Core Services and Dependency Injection
233
234
Essential services for component I/O management, reflection utilities, and dependency injection infrastructure.
235
236
```typescript { .api }
237
interface DynamicComponentInjector {
238
componentRef: ComponentRef<unknown> | null;
239
}
240
241
const DynamicComponentInjectorToken: InjectionToken<DynamicComponentInjector>;
242
243
@Injectable({ providedIn: 'root' })
244
export class IoFactoryService {
245
create(
246
componentInjector: DynamicComponentInjector,
247
ioOptions?: IoServiceOptions & IoFactoryServiceOptions
248
): IoService;
249
}
250
251
@Injectable()
252
export class IoService implements OnDestroy {
253
update(inputs?: InputsType | null, outputs?: OutputsType | null): void;
254
}
255
```
256
257
[Core Services](./core-services.md)
258
259
## Module Integration
260
261
ng-dynamic-component supports both standalone components and NgModule-based applications:
262
263
### Standalone Usage
264
265
```typescript
266
import { DynamicComponent, DynamicIoDirective } from 'ng-dynamic-component';
267
268
@Component({
269
standalone: true,
270
imports: [DynamicComponent, DynamicIoDirective],
271
template: `<ndc-dynamic [ndcDynamicComponent]="comp"></ndc-dynamic>`
272
})
273
export class MyComponent { }
274
```
275
276
### NgModule Usage
277
278
```typescript
279
import { DynamicModule } from 'ng-dynamic-component';
280
281
@NgModule({
282
imports: [DynamicModule],
283
// ...
284
})
285
export class MyModule { }
286
```
287
288
### Specialized Module Imports
289
290
For fine-grained control, import specific feature modules:
291
292
```typescript
293
import {
294
DynamicModule, // Core dynamic component + I/O
295
DynamicIoModule, // Just I/O directives
296
DynamicAttributesModule, // Dynamic attributes only
297
DynamicDirectivesModule, // Dynamic directives only
298
ComponentOutletInjectorModule // NgComponentOutlet enhancements only
299
} from 'ng-dynamic-component';
300
301
@NgModule({
302
imports: [
303
DynamicModule, // Main module with all features
304
// OR import specific features:
305
// DynamicIoModule, // Dynamic I/O directives
306
// DynamicAttributesModule, // Dynamic attributes directive
307
// DynamicDirectivesModule, // Dynamic directives (experimental)
308
// ComponentOutletInjectorModule, // NgComponentOutlet enhancements
309
],
310
// ...
311
})
312
export class FeatureModule { }
313
```