Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dynamically instantiate an ng-template and create HTML in angular 5

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 the value to it, and return the rendered HTML to typeahead.js in my suggest function.

like image 660
Jim Avatar asked Feb 22 '18 08:02

Jim


People also ask

Can I use ng-template without ngIf?

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.

What is HTML ng-template?

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.

What is difference between ng-template and Ng container?

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.


1 Answers

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

like image 183
yurzui Avatar answered Sep 21 '22 01:09

yurzui