最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Can't get dynamic data from innerHTML - Angular - Stack Overflow

programmeradmin0浏览0评论

I am grabbing dynamic data from my view or HTML placing it on my page so I can view the print out of said data. I have to use this method because I am creating my own print page with this dynamic data on it. The method that I am using grabs the first initial value and not the latest updated DOM. If I remove the .innerHTML I am able to see the dynamic data, however unsure if there's a way to get that data without .innerHTML.

TS

click(data){
this.newData = data
let printContents, popupWin;
    if(document.getElementById('print-section') != null){
      printContents = document.getElementById('print-section').innerHTML;
      popupWin = window.open('', '_blank', 'top=0,left=0,height=100%,width=auto');
      popupWin.document.open();
      popupWin.document.write(`
        <html>
          <head>
            <title>Print tab</title>
            <style>
            //........Customized style.......
            </style>
          </head>
          <body onload="window.print();window.close()">${printContents}</body>
        </html>`
      );
      popupWin.document.close();
    }

}

HTML

<div id="print-section" style="display:none">
        <div>
            <p>{{newData.id}}</p>
        </div>
 </div>

I am grabbing dynamic data from my view or HTML placing it on my page so I can view the print out of said data. I have to use this method because I am creating my own print page with this dynamic data on it. The method that I am using grabs the first initial value and not the latest updated DOM. If I remove the .innerHTML I am able to see the dynamic data, however unsure if there's a way to get that data without .innerHTML.

TS

click(data){
this.newData = data
let printContents, popupWin;
    if(document.getElementById('print-section') != null){
      printContents = document.getElementById('print-section').innerHTML;
      popupWin = window.open('', '_blank', 'top=0,left=0,height=100%,width=auto');
      popupWin.document.open();
      popupWin.document.write(`
        <html>
          <head>
            <title>Print tab</title>
            <style>
            //........Customized style.......
            </style>
          </head>
          <body onload="window.print();window.close()">${printContents}</body>
        </html>`
      );
      popupWin.document.close();
    }

}

HTML

<div id="print-section" style="display:none">
        <div>
            <p>{{newData.id}}</p>
        </div>
 </div>
Share Improve this question asked Jan 10, 2018 at 3:16 userlkjsflkdsvmuserlkjsflkdsvm 9831 gold badge23 silver badges54 bronze badges 4
  • could you attach a plunk please? – Vishal Commented Jan 10, 2018 at 3:24
  • You can instead use [inner HTM] attribute binding – Aravind Commented Jan 10, 2018 at 3:32
  • @Aravind he is trying to get the html content not setting in template. Property binding is not the solution. I rement using ViewChild. See my answer below. – Vishal Commented Jan 10, 2018 at 3:40
  • 1 @VishalGulati is correct, I will check your solution. – userlkjsflkdsvm Commented Jan 10, 2018 at 3:54
Add a ment  | 

2 Answers 2

Reset to default 3

You get the old content of the element because Angular's change detection mechanism did not update the DOM between the change to this.newData and the statement where you get the content of the div. The HTML output will be updated only after the current execution cycle.

You can force change detection with several techniques (see this answer). One of them is by calling ChangeDetector.detectChanges().

By the way, Angular's way to access DOM elements in code is with @ViewChild(varname) and template reference variables, instead of calling document.getElementById.

<div #printSection style="display:none">
  <div>
    <p>{{newData.id}}</p>
  </div>
</div>
import { Component, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core';

export class MyComponent {

  @ViewChild("printSection") printSectionRef: ElementRef;

  constructor(private changeDetector: ChangeDetectorRef) {
  }

  click(data) {
    this.newData = data
    this.changeDetector.detectChanges(); // Trigger change detection
    let printContents, popupWin;
    if (this.printSectionRef && this.printSectionRef.nativeElement){
      printContents = this.printSectionRef.nativeElement.innerHTML;
      ...
    }
  } 
}

I rement using ViewChild: Child ponents in our view can be accessed from our parent ponent easily with @ViewChild.

<div id="print-section" #printContainer style="display:none">
        <div>
            <p>{{newData.id}}</p>
        </div>
</div>

In ponent:

export class MyComponent{
  @ViewChild('printContainer') private printContainer: ElementRef; //import ElementRef
  constructor() {
  }

}

click method:

click(data){
this.newData = data
let printContents, popupWin;
    if(document.getElementById('print-section') != null){
      printContents = this.printContainer.nativeElement.innerHTML;

      // rest all remains same
    }

}

Also check this very similar question on how to perform DOM manipulation in Angular Components!

发布评论

评论列表(0)

  1. 暂无评论