angularng-bootstrapdependency-resolver

references to Component functionality within innerHTML not working


Trying to get ngbTooltip to work within the secure confines of innerHTML. At first I thought this doesn't work cause the data to be inserted is retrieved a-synchronously and view rendering + strapping ngB-functionality is already done, so Implemented Route-resolving. Everything resolves fine before the view gets rendered, however,.. tooltip is still not working.

Please note (!) that when the tooltip is hard-coded in the according template stuff just works, as is other ngB-functionality, etc...

The tooltip is just a trivial example. I need more stuff to function, things like Modals, PopOvers, references to functions in the component.

Looked in the Dom after rendering and its just normal HTML in there, no isolated scope or what so over.

Component

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent {
  quote: string;
  isLoading = false;

  public sanitizedHtml: any;

  constructor(private portareServices: PortareServices,
    private sanitizer: DomSanitizer,
    private route: ActivatedRoute
  ) {
    this.sanitizedHtml = this.sanitizeHTMLstring(this.route.snapshot.data.content.pageContent);
  }

  public sanitizeHTMLstring(htmlStr: string) {
    return this.sanitizer.bypassSecurityTrustHtml(htmlStr);
  }
}

Routing

const routes: Routes = [
  {
    path: 'content',
    resolve: {
      content: ContentResolve
    },
    component: HomeComponent,
    pathMatch: 'full'
  },
  {
    path: '**',
    redirectTo: '',
    resolve: {
      content: ContentResolve
    },
    component: HomeComponent,
    pathMatch: 'full'
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: []
})
export class AppRoutingModule { }

Example JSON with the HTML to be inserted

{ "pageContent": "<button type=\"button\" class=\"btn btn-outline-secondary mr-2\" placement=\"bottom\" [ngbTooltip]=\"htmlContent\">Tooltip on top<\/button>" }


Solution

  • You can specify the element type in the data structure, along with the tooltip content:

    data = { type: "input", content: "My initial text", tooltip: "This is a tooltip" };
    data = { type: "button", content: "My caption", tooltip: "Hello world!" };
    

    In the template, the appropriate element is inserted with an ng-switch directive. The tooltip content, and possibly other values, are supplied through data binding:

    <ng-container [ngSwitch]="data.type">
      <button *ngSwitchCase="'button'" ... [ngbTooltip]="data.tooltip">{{data.content}}</button>
      <input *ngSwitchCase="'input'" ... [ngbTooltip]="data.tooltip" [value]="data.content">
    </ng-container>
    

    See this stackblitz for a demo.