Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Render view inside iframe in Angular 6 and continue to use template variables

In angularJS, you could use $compile to render a view in an iframe as well as keep the angularjs $scope variables within the iframe. Is there an equivalent functionality in Angular.IO?

AngularJS equivalent in a directive:

var $body = angular.element($element[0].contentDocument.body);
var template = $compile(contents)($scope);
$body.append(template);

I would like to render an iframe, pass the necessary html to populate the iframe and be able to use the template language inside the iframe html.

Similar to this but, this plunkr isn't working. It doesn't render the variables in the iframe view.

Update: Found some tutorials on how to use angularJS in typescript and that might work. Ultimately, I would like to share variables between the parent and iframe, similar to how $scope in angularJS can be shared between parent and iframe.

like image 369
Tim Joyce Avatar asked Sep 11 '18 18:09

Tim Joyce


People also ask

Can I hide content inside an iframe from an external domain?

Can I hide content inside an iframe from an external domain? Yes totally doable. Once you assign the parameter to a var, you could then do anything you want… like a hide() on an element.

Can I use iframe in angular?

When the iframeSettings option is enabled, the Rich Text Editor creates the iframe element as the content area on control initialization. It is used to display and editing the content in content area. The editor will display only the body tag of a < iframe > document.

Can an iframe contains another iframe?

After some research I found that you can't nest an iframe inside of an iframe in the same file. Instead what you need to do is add a reference to the child iframe as the src attribute for the parent iframe.

What are the elements that we can use in angular templates?

This template uses typical HTML elements like <h2> and <p> . It also includes Angular template-syntax elements, *ngFor , {{hero.name}} , (click) , [hero] , and <app-hero-detail> . The template-syntax elements tell Angular how to render the HTML to the screen, using program logic and data.


1 Answers

You can get the iframe Window and inject a variable from the Angular component, you might to inject a Subject so you can trigger changes (FULL DEMO) inside the iframe like this:

Here is the template component

<hello name="{{ name }}"></hello>
<button (click)="sendData()">Click Here</button>
<iframe #iframe frameborder="1" width="100%" height="50%"></iframe>

And here is the logic:

import { Component, ViewChild, ElementRef, OnInit } from '@angular/core';
import { Subject } from 'rxjs/Subject';

const iframeCode = `
  <h1>Hello World</h1>

  <script type="text/javascript">
    if (dataFromParent) {
      // Subscribe to the Subject so you can trigger changes from Angular
      dataFromParent.subscribe(res => {
        document.querySelector('h1').innerHTML = res;
      })
    }
  </script>
`

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
  data$: Subject<string> = new Subject('');
  @ViewChild('iframe') iframe: ElementRef;

  name = 'Angular';

  ngOnInit() {
    this.setIframeReady(this.iframe);
  }

  sendData() {
    this.data$.next('From parent to iframe');
  }

  private setIframeReady(iframe: ElementRef): void {
    const win: Window = iframe.nativeElement.contentWindow;

    // Pass the variable from parent to iframe
    win['dataFromParent'] = this.data$;

    const doc: Document = win.document;
    doc.open();
    doc.write(iframeCode);
    doc.close()
  }
}

Also, if you want to communicate from iframe to parent you could use CustomEvent.

Hope it help.

like image 107
fmontes Avatar answered Jan 01 '23 23:01

fmontes