I have a component like:
@Component({
selector: 'app-item',
template: '<p>{{title}}</p>'
})
export class TitleComponent {
@Input() title:string;
}
@Component({
selector: 'app-foo',
template: '<ng-container *ngComponentOutlet="outlet"></ng-container>'
})
export class FooComponent {
outlet = TitleComponent;
}
How do you pass input title value on the ng-container for the TitleComponent or how can I set this value?
NgComponentOutletlinkInstantiates a Component type and inserts its Host View into the current View. NgComponentOutlet provides a declarative approach for dynamic component creation.
ComponentFactorylinkBase class for a factory that can create a component dynamically. Instantiate a factory for a given type of component with resolveComponentFactory() . Use the resulting ComponentFactory. create() method to create a component of that type. Deprecated: Angular no longer requires Component factories.
What dynamic components are. Dynamic means, that the components location in the application is not defined at buildtime. That means, that it is not used in any angular template. Instead, the component is instantiated and placed in the application at runtime.
As Reno has already mentioned, you can use an injector to inject values.
For the sake of completeness, here is an example with a dynamic "title" value:
export const TITLE = new InjectionToken<string>('app.title');
@Component({
selector: 'app-item',
template: '<p>{{title}}</p>'
})
export class TitleComponent implements OnInit {
@Input() title:string;
constructor(@Inject(TITLE) private titleInjected: string){
}
ngOnInit() {
this.title = this.title || this.titleInjected;
}
}
@Component({
selector: 'app-foo',
template: '<ng-container *ngComponentOutlet="outlet; injector: myInjector"></ng-container>'
})
export class FooComponent {
outlet = TitleComponent;
myInjector: Injector;
constructor(injector: Injector){
let title = 'My dynamic title works!';
this.myInjector = ReflectiveInjector.resolveAndCreate([{ provide: TITLE, useValue: title }], injector);
}
}
@NgModule({
providers: [
{ provide: TITLE, useValue: '' }
]
})
export class AppModule { }
An example solution is shown in the ngComponentOutlet documentation, specifically the second example with the @Injectable
, as titusfx also mentioned.
Here is what it would look like with your use case:
@Injectable()
class Info {
title = 'a little hacky';
}
@Component({
selector: 'app-item',
template: '<p>{{info.title}}</p>'
})
export class TitleComponent {
// @Input() title:string;
constructor(public info: Info){ }
}
@Component({
selector: 'app-foo',
template: '<ng-container *ngComponentOutlet="outlet; injector: myInjector"></ng-container>'
})
export class FooComponent {
outlet = TitleComponent;
myInjector: Injector;
constructor(injector: Injector){
this.myInjector = ReflectiveInjector.resolveAndCreate([Info], injector);
}
}
Consider using ng-dynamic-component library to work with dynamic components.
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