1

I know its not possible to inject angular directive along html code inside inner html, is there any work around it? I'm trying to read the html and the directive from a html file and inject it inside a div, I thought about using component factory and create the component dynamically but the directive in the html file can be anywhere in the code not sure how I can append it to the right place in dom, I don't have much experience working with component factory so please let me know if there is a way.

ngOnInit(): void {

    let loading = this.loadingService.addTask();

    this.route.paramMap
        .take(1)
        .subscribe(params => {
            let page: string = params.get("page") || "";

            if (page) {
                this.trainingService.getPageContent(page)
                    .take(1)
                    .subscribe(res => {
                        this.content = res;
                        this.loadingService.completeTask(loading);
                    })
            }
            else {
                this.loadingService.completeTask(loading);
            }
        },
        error => {
            this.notificationService.error("Error retrieving training page", error);

            this.loadingService.clearAllTasks();
        })

here is my template

<div [innerHtml]="content"></div>

here is an html page example that should be injected (this is an external html page file)

<div class="row">
    <div class="col-md-12">
        <div class="panel panel-default b">
            <div class="panel-body">
                <div class="row">
                    <!--the directive-->
                    <sa-azure-media-player [source]="the link"></ss-azure-media-player>
                </div>
            </div>
        </div>
    </div>
</div>
DeadlyDagger
  • 109
  • 1
  • 12
  • Are you talking about injecting html from one component to another? – Nicholas K Jan 20 '20 at 17:43
  • I read the html from an external html file and then inject it. – DeadlyDagger Jan 20 '20 at 17:50
  • Unless you control the html source, it's a really bad idea to inject it into your app. If you really want to do this, inject `Sanitizer` and run the content through `bypassSecurityTrustHtml` before binding it to `innerHtml` – The Head Rush Jan 20 '20 at 18:03
  • You can use DomPortalOutlet from CDK. https://github.com/angular/material.angular.io/blob/master/src/app/shared/doc-viewer/doc-viewer.ts#L103 – Nifiro Jan 20 '20 at 18:04
  • I am the only one who controls the html source, can you give me some information about that approach? any link or example I can look at? – DeadlyDagger Jan 20 '20 at 18:06
  • I think understanding what compiled angular code looks like can help you understand the problem here. Check [this article](https://medium.com/angular-in-depth/a-deep-deep-deep-deep-deep-dive-into-the-angular-compiler-5379171ffb7a) out. Your HTML / Typescript is all compiled to minified JS by the compiler. So, the only option is to use the angular compiler to JIT compile your component. Take a look at [this answer](https://stackoverflow.com/a/42065289/3718246) and give that a try. – Dean Jan 20 '20 at 19:18

1 Answers1

2

There isn't a way to do this. The workaround would be to change the way you inject html. Instead of injecting as html, write a sub-component, give it the right info (as an [json-]object!), and off you go.

In case you do not have control of the incoming info (in your case html), you are forced to mould it into an object, so you can use it in angular.

In a recent project I had to have text content that might contain iframes (iframes don't work well in angular). The solution was to parse and save the content in the backend as a JSON-object containing text- and iframe-parts in the right order (that cost some time, unfortunately). Once I got hold of it in Angular, I could inject the texts and iframes of the JSON-object by using typescript. And, of course, do the right thing for the right element.

So, in case you have control over the incoming info (be it html or whatever kind of identifiable object), that's where you should change the procedure (and make full use of the angular MVC-stuff). In case you do not have control over that, please provide some more details as to what needs to be done and what the cicumstances are.

Klaassiek
  • 2,795
  • 1
  • 23
  • 41