Angular 5在不渲染的情况下生成HTML

Angular 5在不渲染的情况下生成HTML,html,angular,angular-components,Html,Angular,Angular Components,是否可以通过绕过组件所需的所有数据而不在浏览器视口中实际渲染来从组件生成html文件? 我只想生成一些html代码,将其发送到从该html生成PDF的后端。我认为您不能,因为angular组件的呈现严重依赖于它的生命周期挂钩 不过,我可以想出一种伪装的方法: 从代码实例化不可见组件 将其添加到DOM中,使其行为类似于任何常规组件 检索它的HTML 最后摧毁它 应用程序模块.ts @Component({ selector: 'my-app', templateUrl: './app

是否可以通过绕过组件所需的所有数据而不在浏览器视口中实际渲染来从组件生成html文件?
我只想生成一些html代码,将其发送到从该html生成PDF的后端。

我认为您不能,因为angular组件的呈现严重依赖于它的生命周期挂钩

不过,我可以想出一种伪装的方法:

  • 从代码实例化不可见组件
  • 将其添加到DOM中,使其行为类似于任何常规组件
  • 检索它的HTML
  • 最后摧毁它

应用程序模块.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));
    })
  }
}
请注意,我已将
PdfContentComponent
添加到模块的
entryComponents
。 这对于要从代码实例化的任何组件都是必需的

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, PdfContentComponent ],
  bootstrap:    [ AppComponent ],
  entryComponents :  [ PdfContentComponent ]
})
export class AppModule { }
pdf content.component.html

<span>Hello, {{ name }}</span>
<button (click)='printPdf()'>Hit me!</button>

<ng-container #pdfContainer>
</ng-container>
app.component.html

<span>Hello, {{ name }}</span>
<button (click)='printPdf()'>Hit me!</button>

<ng-container #pdfContainer>
</ng-container>
打我!
应用程序组件.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));
    })
  }
}
@组件({
选择器:“我的应用程序”,
templateUrl:“./app.component.html”,
样式URL:['./app.component.css']
})
导出类AppComponent{
//pdf内容将简要添加到此容器中
@ViewChild(“pdfContainer”,{read:ViewContainerRef})容器;
建造师(
专用解析程序:ComponentFactoryResolver
) {}
printPdf(){
//获取PdfContentComponent工厂
常量工厂:ComponentFactory=this.resolver.resolveComponentFactory(PdfContentComponent);
//实例化PdfContentComponent
const pdfContentRef=this.container.createComponent(工厂);
//从引用中获取实际实例
const pdfContent=pdfContentRef.instance;
//更改组件的某些输入属性
pdfContent.name='John Doe';
//等待组件完成初始化
//并短暂延迟事件侦听器,
所以我们不会在盎格鲁的生命周期中进行清理。
const sub=pdfContent.loaded
.管道(延迟(1))
.订阅(()=>{
//停止侦听加载的事件
sub.取消订阅();
//在此处将html发送到后端
alert(pdfContent.element.nativeElement.innerHTML);
//从DOM中删除该组件
this.container.remove(this.container.indexOf(pdfContentRef));
})
}
}

您可以使用angular提供的
渲染器2
类。试试这个示例代码

从'@angular/core'导入{Component,Renderer2,OnInit};
....
构造函数(专用渲染器:渲染器2){
}
恩戈尼尼特(){
const div:htmldevelment=this.renderer.createElement('div');
const text=this.renderer.createText('Hello world!');
this.renderer.appendChild(div,text);
console.log(div.outerHTML);
}

是否也可以在Renderer2内部创建具有输入属性的角度组件?