是否可以通过绕过组件所需的所有数据而无需在浏览器视口中实际呈现它的方式从组件生成html文件? 我只想生成一些html代码,以将其发送到从此html生成PDF的后端。
答案 0 :(得分:1)
我认为您无法做到,因为angular组件的渲染在很大程度上依赖于生命周期挂钩。
不过,我可以想到一种伪造它的方法:
Here's a working code example。
app.module.ts
请注意,我已将PdfContentComponent
添加到模块的entryComponents
中。
您要从代码实例化的任何组件都是必需的。
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ AppComponent, PdfContentComponent ],
bootstrap: [ AppComponent ],
entryComponents : [ PdfContentComponent ]
})
export class AppModule { }
pdf-content.component.html
<span>Hello, {{ name }}</span>
pdf-content.component.ts
请注意host: {style: 'display: none'}
,这将使该组件有效地不可见
@Component({
selector: 'my-pdf-content',
templateUrl: './pdf-content.component.html',
host: {
style: 'display: none'
}
})
export class PdfContentComponent implements OnInit {
@Input() name: string;
@Output() loaded: EventEmitter<void> = new EventEmitter<void>();
constructor(public element:ElementRef) {
}
ngOnInit() {
this.loaded.emit();
}
}
app.component.html
<button (click)='printPdf()'>Hit me!</button>
<ng-container #pdfContainer>
</ng-container>
app.component.ts
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
// the pdf content will be briefly added to this container
@ViewChild("pdfContainer", { read: ViewContainerRef }) container;
constructor(
private resolver: ComponentFactoryResolver
) {}
printPdf() {
// get the PdfContentComponent factory
const factory: ComponentFactory<any> = this.resolver.resolveComponentFactory(PdfContentComponent);
// instantiate a PdfContentComponent
const pdfContentRef = this.container.createComponent(factory);
// get the actual instance from the reference
const pdfContent = pdfContentRef.instance;
// change some input properties of the component
pdfContent.name = 'John Doe';
// wait for the component to finish initialization
// and delay the event listener briefly,
// so we don't run the clean up in the middle of angulars lifecycle pass
const sub = pdfContent.loaded
.pipe(delay(1))
.subscribe(() => {
// stop listening to the loaded event
sub.unsubscribe();
// send the html to the backend here
window.alert(pdfContent.element.nativeElement.innerHTML);
// remove the component from the DOM
this.container.remove(this.container.indexOf(pdfContentRef));
})
}
}
答案 1 :(得分:1)
您可以使用angular提供的Renderer2
类。试试这个示例代码;
import { Component, Renderer2, OnInit } from '@angular/core';
....
constructor(private renderer: Renderer2){
}
ngOnInit(){
const div: HTMLDivElement = this.renderer.createElement('div');
const text = this.renderer.createText('Hello world!');
this.renderer.appendChild(div, text);
console.log(div.outerHTML);
}