-
Notifications
You must be signed in to change notification settings - Fork 26.9k
Closed
Labels
area: commonIssues related to APIs in the @angular/common packageIssues related to APIs in the @angular/common packagefeatureIssue that requests a new featureIssue that requests a new feature
Description
I'm submitting a ... (check one with "x")
[ ] bug report => search github for a similar issue or PR before submitting
[ x ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior
None
Expected/desired behavior
A directive that is able to create components dynamically, the same way as NgTemplateOutlet created embedded view dynamically.
Pros
- Remove the boilerplate in a component. Developer does not need to query (
ViewChild) and manually create the component. (ComponentFactoryResolver,ViewContainerRef) - Expressed in the template.
- Simple
- Aligned with NgTemplateOutlet, same idea same concept
Cons
- Host attribute bindings are not expressed in a template. Not much of a con, as its expected and
ComponentRefcan be used to set values on the instance... - Getting a reference to the returned
ComponentRefis via callback only. - more ?
Directive
@Directive({
selector: '[swapCmp]'
})
export class SwapComponentDirective {
private component: any;
constructor(private cfr: ComponentFactoryResolver,
private vcRef: ViewContainerRef,
private tRef: TemplateRef<Object>) {
}
@Input() swapCmpBindings: ResolvedReflectiveProvider[];
@Input() swapCmpInjector: Injector;
@Input() swapCmpProjectables: any[][];
@Output() onCreate: EventEmitter<ComponentRef<any>> = new EventEmitter<ComponentRef<any>>(false);
@Input() set swapCmp(component: any) {
this.component = component;
this.vcRef.clear();
if (this.component) {
let injector = this.swapCmpInjector || this.vcRef.parentInjector;
if (Array.isArray(this.swapCmpBindings) && this.swapCmpBindings.length > 0) {
injector = ReflectiveInjector.fromResolvedProviders(this.swapCmpBindings, injector);
}
const cmpRef = this.vcRef.createComponent(
this.cfr.resolveComponentFactory(component),
this.vcRef.length,
injector,
this.swapCmpProjectables
);
cmpRef.changeDetectorRef.detectChanges();
this.onCreate.emit(cmpRef);
}
}
} <template [swapCmp]="ctx.component" [swapCmpBindings]="ctx.bindings" [swapCmpInjector]="ctx.injector" [swapCmpProjectables]="ctx.projectableNodes"></template>
The name here is SwapComponent but it just as an example, took it from my code base
- A Developer provides a component, changing the component will re-create.
- Injector is optional, if not supplied the current injector is used.
- Bindings are used to allow additional providers to the injector (something like
viewProviders) - In case
ng-contentis needed the developer can supply projectableNodes.
What do you think?
mikerob215, meriturva, mlc-mlapis, cyberbobjr, rupebac and 11 moreganqqwerty and ikismail
Metadata
Metadata
Assignees
Labels
area: commonIssues related to APIs in the @angular/common packageIssues related to APIs in the @angular/common packagefeatureIssue that requests a new featureIssue that requests a new feature