angular2-dynamic-component & angular2-dynamic-directive
An implementation of dynamic component wrapper at Angular2 4.1.2 .
Also, you must see the solution out of the box before using this component: (NgComponentOutlet, since 4.0.x)
https://angular.io/docs/ts/latest/api/common/index/NgComponentOutlet-directive.html
Description
Date of creation: 18 Jun [starting with Angular 2.0.0-rc.2].
Installation
1 At first, you need to install the core-js npm module.
2 Then you need to install the ts-metadata-helper dependency package (don't worry, it's very small and simple, I like "reusable" approach)
npm install ts-metadata-helper --save
3 And after that, you have to install the target package
npm install angular2-dynamic-component --save
4 Then you must apply the DynamicComponentModule
import { DynamicComponentModule } from ' angular2-dynamic-component/index ' ;
@ NgModule ( {
imports : [ DynamicComponentModule ]
} )
Demo
1 git clone --progress -v "git@github.com :apoterenko/angular2-dynamic-component.git" "D:\sources"
2 cd D:\sources\angular2-dynamic-component\demo
3 npm install
4 npm start
Features
1 Support of dynamicComponentReady & dynamicComponentBeforeReady output events. See below.
2 Support of dynamic-component directive. See below.
3 Support of DynamicComponent component. See below.
4 Support of Dynamic within Dynamic strategy (see demo inside).
@ Component ( ... )
export class AppComponent {
extraTemplate = ` <DynamicComponent [componentTemplate]='"<span>Dynamic inside dynamic!</span>"'></DynamicComponent> ` ;
extraModules = [ DynamicComponentModule ] ;
...
}
< template dynamic-component
[ componentModules ]= " extraModules "
[ componentTemplate ]= ' extraTemplate ' > </ template >
5 Support of componentTemplateUrl attribute. This attribute allows getting resource via Angular2 HTTP/Ajax.
Also, 301, 302, 307, 308 HTTP statuses are supported (recursive redirection). The componentRemoteTemplateFactory (IComponentRemoteTemplateFactory)
attribute allows prepare http response before rendering.
@ Component ( ... )
export class AppComponent {
dynamicCallback ( scope ) {
console . log ( ' Hi there! Context value is: ' , scope . contextValue ) ;
}
}
< template dynamic-component
( dynamicComponentReady )= " dynamicCallback($event) "
[ componentContext ]= " {contextValue: 100500} "
[ componentDefaultTemplate ]= ' "<span style=\"color: red\">This is fallback template</span>" '
[ componentTemplateUrl ]= ' " https://test-cors.appspot.com " ' > </ template >
6 Support of componentContext attribute.
This attribute can refer to owner component (via self = this) or any other object.
@ Component ( ... )
export class AppComponent {
self = this ;
dynamicContextValue = 100500 ;
changedValue = 0 ;
dynamicExtraModules = [ FormsModule ] ;
}
< template dynamic-component
[ componentContext ]= " self "
[ componentModules ]= " dynamicExtraModules "
[ componentTemplate ]= ' "<span [innerHTML]=\"changedValue\"></span><input type=\"text\" [(ngModel)]=\"dynamicContextValue\" (ngModelChange)=\"changedValue = $event\">" ' > </ template >
7 Support of dynamic injected modules via the DynamicComponentModuleFactory .
The CommonModule module is imported by default.
import { DynamicComponentModuleFactory } from " angular2-dynamic-component/index " ;
@ NgModule ( {
imports : [ ... ,
DynamicComponentModuleFactory . buildModule ( [
FormsModule
] )
] ,
...
bootstrap : [ AppComponent ]
} )
export class AppModule { }
< template dynamic-component
[ componentContext ]= " {dynamicContextValue: 100500, changedValue: 0} "
[ componentTemplate ]= ' "<span [innerHTML]=\"changedValue\"></span><input type=\"text\" [(ngModel)]=\"dynamicContextValue\" (ngModelChange)=\"changedValue = $event\">" ' > </ template >
8 Support of componentModules attribute.
@ Component ( ... )
export class AppComponent {
dynamicExtraModules = [ FormsModule ] ;
}
< template dynamic-component
[ componentModules ]= " dynamicExtraModules "
[ componentContext ]= " {dynamicContextValue: 100500, changedValue: 0} "
[ componentTemplate ]= ' "<span [innerHTML]=\"changedValue\"></span><input type=\"text\" [(ngModel)]=\"dynamicContextValue\" (ngModelChange)=\"changedValue = $event\">" ' > </ template >
9 Support of componentType attribute.
< template dynamic-component
* ngFor = " let field of columns "
[ componentType ]= " field.type "
[ componentContext ]= " field.context " >
</ template >
@ Component ( ... )
export class AppComponent {
columns = [ {
type : TextField ,
context : {
fieldName : ' description ' ,
value : ' Test description '
}
} , {
type : CheckboxField ,
context : {
fieldName : ' expired ' ,
value : true
}
} ] ;
ngOnInit ( ) {
setTimeout ( ( ) => {
console . log ( JSON . stringify ( this . columns ) ) ;
} , 3000 ) ;
}
import {
Component ,
Input ,
} from ' @angular/core ' ;
@ Component ( {
selector : ' DynamicTextField ' ,
template : ` < input name = " {{fieldName}} " type = " text " [ value ]= " value " > ` ,
} )
export class TextField {
@ Input ( ) fieldName : string ;
@ Input ( ) value : string ;
constructor (
private appState : AppState ,
private elementRef : ElementRef ,
private appRef : ApplicationRef
) {
console . log ( ' The TextField constructor has been called ' ) ;
}
ngOnInit ( ) {
setTimeout ( ( ) => this . value = this . fieldName + ' : next value ' , 4000 ) ;
this . elementRef . nativeElement . childNodes [ 0 ] . style . color = ' red ' ;
}
}
@ Component ( {
selector : ' DynamicCheckboxField ' ,
template : ` < input name = " {{fieldName}} " type = " checkbox " [ checked ]= " value " > ` ,
} )
export class CheckboxField {
@ Input ( ) fieldName : string ;
@ Input ( ) value : boolean ;
constructor ( ) {
console . log ( ' The CheckboxField constructor has been called ' ) ;
}
ngOnInit ( ) {
setTimeout ( ( ) => this . value = ! this . value , 1000 ) ;
}
}
10 Support of componentTemplatePath attribute. This analogue of templateUrl parameter for @Component .
License
Licensed under MIT.