I am trying to build a typeahead.js component for use in Angular 5. I have a working plunker, as far as I can get it working.
When the component, type-head
is declared, an ng-template
is supplied to the component.
<type-head>
<ng-template #hint let-hint="hint">name: {{hint.name}}</ng-template>
</type-head>
Each hint should display name: sam|frodo|pippin
etc.
The type-head
component is declared as follows:
@Component({
selector: 'type-head',
template: `
<input #input class="form-control" />
<ng-content #content></ng-content>
`
})
When the typeahead.js
component needs to display a hint, it executes a callback, the suggest
method which should return HTML content.
At the moment my implementation is as follows:
/**
* TODO: REPLACE THIS FUNCTION WITH A DYNAMIC TEMPLATE
*/
suggest(value:any) {
return $("<div>name: " + value.name + "</div>");
}
I want to replace this implementation with an implementation that uses the ng-template
. I can render the template using *ngTemplateOutlet
, but I don't know how to do it dynamically so I can return the HTML.
My question is:
How do I load up the
#hint
ng-template
, bind thevalue
to it, and return the rendered HTML totypeahead.js
in mysuggest
function.
ng-template should be used along with structural directives like [ngIf],[ngFor],[NgSwitch] or custom structural directives. That is why in the above example the contents of ng-template are not displayed. ng-template never meant to be used like other HTML elements.
ng-template is an Angular element that is used for rendering HTML in a template. However, it is not rendered directly on DOM. If you include an ng-template tag to a template, the tag and the content inside it will be replaced by comment upon render.
ng-container serves as a container for elements which can also accept structural directives but is not rendered to the DOM, while ng-template allows you to create template content that is not rendered until you specifically (conditionally or directly) add it to the DOM.
You can use TemplateRef::createEmbeddedView
method to create embedded view and then obtain DOM node to pass to typeahead as a template:
parent.html
<type-head>
<ng-template #hint let-hint="hint">
<div>name: {{hint.name}}</div>
</ng-template>
</type-head>
component.ts
@ContentChild(TemplateRef) templateRef: TemplateRef<any>;
suggest(value:any) {
const embeddedView = this.templateRef.createEmbeddedView({ hint: value });
embeddedView.detectChanges();
this.embeddedViews.push(embeddedView);
return embeddedView.rootNodes[1];
}
Plunker Example
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