I managed to do that using TemplateRef's private API. Here's the function I use at the moment :
@ContentChildren(TemplateRef) templates: QueryList<TemplateRef<any>>;
getTemplate(id: string): TemplateRef<any> {
// FIXME: Should not use private API...
return this.templates ? this.templates.find((template: any) =>
template._def.references[id]) : null;
}
But this doesn't work with a production build, actually I found your post looking for another solution, I'll update if I find something or submit a feature request to Angular github.
In the meantime I thought it would be worth sharing.
-- EDIT --
It really looks like there is a possible solution using a structural directive.
You'll learn in this guide that the asterisk (*) is a convenience notation and the string is a microsyntax rather than the usual template expression. Angular desugars this notation into a marked-up <ng-template>
that surrounds the host element and its descendents. Each structural directive does something different with that template.
Link to documentation
-- EDIT 2 --
Ok it works with a directive that retrieve the TemplateRef, but for the moment I register it to a service using an id, I don't use ViewChildren/ContentChildren anymore. My Component which use *ngTemplateOutlet directive then retrieve the TemplateRef using the service.
Here's the directive source code :
@Directive({
selector: '[formeTemplate]'
})
export class FormeTemplateDirective {
@Input('formeTemplate') templateId;
constructor(private host: TemplateRef<any>, private service: FormeTemplateService) { }
ngOnInit() {
this.service.register(this.templateId, this.host);
}
}
The service :
@Injectable()
export class FormeTemplateService {
private templates: Array<FormeTemplate>;
constructor() {
this.templates = new Array();
}
register(id: string, ref: TemplateRef<any>) {
this.templates.push(new FormeTemplate(id, ref));
}
getTemplateRef(templateId: string) : TemplateRef<any> {
let template = this.templates.find((template) => template.id === templateId);
return template ? template.ref : null;
}
}