Is there a method that can be used to define an @Input property on an Angular 2 component that's created dynamically?
I'm using the ComponentFactoryResolver to create components in a container component. For example:
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentName); let componentRef = entryPoint.createComponent(componentFactory);
Where "entryPoint" is something like this in the component HTML:
<div #entryPoint></div>
And defined in my container component with:
@ViewChild('entryPoint', { read: ViewContainerRef } entryPoint: ViewContainerRef;
This works well, but I can't find a way to make an @Input property work on the newly created component. I know that you can explicitly set public properties on the component class, but this doesn't seem to work with ng-reflect. Prior to making this change I had a "selected" property decorated with "@Input()" that caused Angular to add the following to the DOM:
<my-component ng-reflected-selected="true"></my-component>
With this in place I was able to dynamically update the markup to switch a CSS class:
<div class="header" [class.active-header]="selected === true"></div>
Based on some searching I was able to find a method to make "@Output" work as expected, but I've yet to find anything for @Input.
Let me know if additional context would be helpful and I'd be happy to add it.
ComponentFactoryResolverlinkUse to obtain the factory for a given component type, then use the factory's create() method to create a component of that type. Deprecated: Angular no longer requires Component factories. Please use other APIs where Component class can be used directly.
Access the ViewContainerRef of an element by placing a Directive injected with ViewContainerRef on the element, or use a ViewChild query. The dependency injector for this view container. Reports how many views are currently attached to this container.
No, Angular2 bindings only work with components and directives statically added to the template of a component.
For all other situations use shared services like explained in https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service
You can also use
let componentRef = entryPoint.createComponent(componentFactory); componentRef.instance.someProp = 'someValue'; componentRef.instance.someObservableOrEventEmitter.subscribe(data => this.prop = data);
The Günter Zöchbauer's answer is correct. But if you, like I was, have troubles with rendering @Input
data in the component template, you should try this:
ngAfterViewInit
.componentRef.instance.ngOnInit()
as a last line.ngOnInit
of your dynamically created component run detectChanges
method of the ChangeDetectorRef
.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With