Iframe внутри компонента angular2, свойство 'contentWindow' не существует в типе 'HTMLElement'

У меня есть iframe внутри компонента angular2, и я пытаюсь изменить содержимое iframe, обратившись к contentWindow.
IFrame должен содержать простую кнопку.

Мой код:

    import { Component } from '@angular/core';
    @Component({
      moduleId: module.id,
      selector: 'component-iframe',
      template: '<iframe id="iframe"></iframe>'
    })
    export class ComponentIframe  {
      constructor() {
        let iframe = document.getElementById('iframe'); 
        let content = '<button id="button" class="button" >My button </button>';
        let doc =  iframe.contentDocument || iframe.contentWindow;
        doc.open();
        doc.write(content);
      doc.close();
    }
   }

Если я комментирую код конструктора и запускаю приложение, он компилируется и запускается правильно. Затем я раскомментирую и все работает отлично (кнопка присутствует в iframe).

Если я разложю код, запустите приложение (запуск npm) У меня есть ошибки компиляции с сообщением:

Свойство 'contentWindow' не существует в типе 'HTMLElement'

.

Я также попробовал альтернативу поместить код бизнес-структуры в ngOnInit(), ngAfterContentInit(), ngAfterViewInit(), но ошибка сохраняется.

Ответ 1

Шаблон не существует в DOM еще при выполнении конструктора

Использовать вместо этого

import { Component, ViewChild, ElementRef } from '@angular/core';
@Component({
  moduleId: module.id,
  selector: 'component-iframe',
  template: '<iframe #iframe></iframe>'
})
export class ComponentIframe  {
  @ViewChild('iframe') iframe: ElementRef;

  ngAfterViewInit() {
    let content = '<button id="button" class="button" >My button </button>';
    let doc =  this.iframe.nativeElement.contentDocument || this.iframe.nativeElement.contentWindow;
    doc.open();
    doc.write(content);
    doc.close();
  }
}

Ответ 2

использовать этот:

let iframe = document.getElementById('iframe') as HTMLIFrameElement

Ответ 3

Я решил проблему следующим образом:

const element: HTMLIFrameElement = document.getElementById('iframe') as HTMLIFrameElement;
const iframe = element.contentWindow;
if (iframe !== null) {
  ...
}

Ответ 4

Если содержимое IFRAME создается с помощью того же источника, я бы предложил использовать атрибут IFRAME srcDoc для установки и изменения содержимого в IFRAME.

@Component({
  selector: 'my-app',
  template: '
    <p><label for="text">Write content here...</label></p>
    <textarea 
        #text
        rows="10" 
        cols="47" 
        placeholder="Write some HTML content here..." 
        [(ngModel)]="srcDocContent"></textarea>

    <p>Preview HTML content in IFRAME</p>
    <iframe 
        sandbox="allow-same-origin" 
        [attr.srcDoc]="srcDocContent"></iframe>
  '
})
export class App {

  srcDocContent:string

  constructor() {
    this.srcDocContent='Some <strong>HTML</strong> content here...'
  }
}

Посмотрите это PLUNKER DEMO

или это Stackblitz DEMO

Это позволит нетронутым элементам HTML оставаться совместимыми с Angular Universal.

Ответ 5

Я решил проблему следующим образом:

 var ID = document.getElementById("Iframe");
 var Iframe = eval("(ID.contentWindow || ID.contentDocument)");
 Iframe.CallIframeFunction();

Ответ 6

Или используйте теперь известную работу над Typescript:

iframe['contentWindow']