我已经创建了接受组件的服务,将该组件添加到我的组件并将它们添加到<body> 。 问题是当我在我的组件中有ng-content来放置传入的组件时,它只是将它添加到ng-content之下,就像appendChild一样。
./service.ts
import { Injectable, Injector, ComponentFactoryResolver, EmbeddedViewRef, ApplicationRef, ComponentRef } from '@angular/core'; import { ModalComponent } from './modal.component'; @Injectable({ providedIn: 'root' }) export class ModalService { constructor( private componentFactoryResolver: ComponentFactoryResolver, private appRef: ApplicationRef, private injector: Injector ) { } appendComponentToBody(component: any) { // Create a component reference from the incoming component let componentRef = this.componentFactoryResolver .resolveComponentFactory(component) .create(this.injector); // Attach incoming component to the appRef so that it's inside the ng component tree this.appRef.attachView(componentRef.hostView); // Get DOM element from incoming component let contentElem = (componentRef.hostView as EmbeddedViewRef<any>) .rootNodes[0] as HTMLElement; // Create a component reference from the service component let componentRefer = this.componentFactoryResolver .resolveComponentFactory(ModalComponent) .create(this.injector); // Attach component to the appRef so that it's inside the ng component tree this.appRef.attachView(componentRefer.hostView); // Get DOM element from service component let domElem = (componentRefer.hostView as EmbeddedViewRef<any>) .rootNodes[0] as HTMLElement; domElem.appendChild(contentElem); // Append DOM element to the body document.body.appendChild(domElem); } }./modal.component.ts
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'modal', template: ` <div> <ng-content> </ng-content> </div> `, styles: [] }) export class ModalComponent implements OnInit { constructor() { } ngOnInit() { } }如果我们提供图片组件,那个服务电话的结果将在正文中:
<modal> <div></div> <app-picture _nghost-c2=""> <p _ngcontent-c2=""> picture works!</p> </app-picture> </modal>期待身体:
<modal> <div> <app-picture _nghost-c2=""> <p _ngcontent-c2=""> picture works!</p> </app-picture> </div> </modal>I have made service which accept component, adding that component to my component and adding them to <body>. Problem is while I have ng-content in my component to place the incoming component, it simply adding it below the ng-content as simply appendChild do.
./service.ts
import { Injectable, Injector, ComponentFactoryResolver, EmbeddedViewRef, ApplicationRef, ComponentRef } from '@angular/core'; import { ModalComponent } from './modal.component'; @Injectable({ providedIn: 'root' }) export class ModalService { constructor( private componentFactoryResolver: ComponentFactoryResolver, private appRef: ApplicationRef, private injector: Injector ) { } appendComponentToBody(component: any) { // Create a component reference from the incoming component let componentRef = this.componentFactoryResolver .resolveComponentFactory(component) .create(this.injector); // Attach incoming component to the appRef so that it's inside the ng component tree this.appRef.attachView(componentRef.hostView); // Get DOM element from incoming component let contentElem = (componentRef.hostView as EmbeddedViewRef<any>) .rootNodes[0] as HTMLElement; // Create a component reference from the service component let componentRefer = this.componentFactoryResolver .resolveComponentFactory(ModalComponent) .create(this.injector); // Attach component to the appRef so that it's inside the ng component tree this.appRef.attachView(componentRefer.hostView); // Get DOM element from service component let domElem = (componentRefer.hostView as EmbeddedViewRef<any>) .rootNodes[0] as HTMLElement; domElem.appendChild(contentElem); // Append DOM element to the body document.body.appendChild(domElem); } }./modal.component.ts
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'modal', template: ` <div> <ng-content> </ng-content> </div> `, styles: [] }) export class ModalComponent implements OnInit { constructor() { } ngOnInit() { } }result of that service call will be in body if we provide picture component:
<modal> <div></div> <app-picture _nghost-c2=""> <p _ngcontent-c2=""> picture works!</p> </app-picture> </modal>expectation in body:
<modal> <div> <app-picture _nghost-c2=""> <p _ngcontent-c2=""> picture works!</p> </app-picture> </div> </modal>最满意答案
作为解决方案,您可以通过将传入的DOM放入模态DOM内的特定标记来执行javascript解决方案。 ./service.ts
import { Injectable, Injector, ComponentFactoryResolver, EmbeddedViewRef, ApplicationRef, ComponentRef } from '@angular/core'; import { ModalComponent } from './modal.component'; @Injectable({ providedIn: 'root' }) export class ModalService { constructor( private componentFactoryResolver: ComponentFactoryResolver, private appRef: ApplicationRef, private injector: Injector ) { } appendComponentToBody(component: any) { // Create a component reference from the incoming component let componentRef = this.componentFactoryResolver .resolveComponentFactory(component) .create(this.injector); // Attach incoming component to the appRef so that it's inside the ng component tree this.appRef.attachView(componentRef.hostView); // Get DOM element from incoming component let contentElem = (componentRef.hostView as EmbeddedViewRef<any>) .rootNodes[0] as HTMLElement; // Create a component reference from the service component let componentRefer = this.componentFactoryResolver .resolveComponentFactory(ModalComponent) .create(this.injector); // Attach component to the appRef so that it's inside the ng component tree this.appRef.attachView(componentRefer.hostView); // Get DOM element from service component let domElem = (componentRefer.hostView as EmbeddedViewRef<any>) .rootNodes[0] as HTMLElement; // Append DOM element to the body document.body.appendChild(domElem); // Add incoming component to modal component domElem.querySelector('#Modal').appendChild(contentElem); } }./modal.component.ts
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'modal', template: ` <div> <div id="Modal"></div> </div> `, styles: [] }) export class ModalComponent implements OnInit { constructor() { } ngOnInit() { } }As solution you can do javascript solution, by putting incoming DOM into specific tag inside modal DOM. ./service.ts
import { Injectable, Injector, ComponentFactoryResolver, EmbeddedViewRef, ApplicationRef, ComponentRef } from '@angular/core'; import { ModalComponent } from './modal.component'; @Injectable({ providedIn: 'root' }) export class ModalService { constructor( private componentFactoryResolver: ComponentFactoryResolver, private appRef: ApplicationRef, private injector: Injector ) { } appendComponentToBody(component: any) { // Create a component reference from the incoming component let componentRef = this.componentFactoryResolver .resolveComponentFactory(component) .create(this.injector); // Attach incoming component to the appRef so that it's inside the ng component tree this.appRef.attachView(componentRef.hostView); // Get DOM element from incoming component let contentElem = (componentRef.hostView as EmbeddedViewRef<any>) .rootNodes[0] as HTMLElement; // Create a component reference from the service component let componentRefer = this.componentFactoryResolver .resolveComponentFactory(ModalComponent) .create(this.injector); // Attach component to the appRef so that it's inside the ng component tree this.appRef.attachView(componentRefer.hostView); // Get DOM element from service component let domElem = (componentRefer.hostView as EmbeddedViewRef<any>) .rootNodes[0] as HTMLElement; // Append DOM element to the body document.body.appendChild(domElem); // Add incoming component to modal component domElem.querySelector('#Modal').appendChild(contentElem); } }./modal.component.ts
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'modal', template: ` <div> <div id="Modal"></div> </div> `, styles: [] }) export class ModalComponent implements OnInit { constructor() { } ngOnInit() { } }
更多推荐
发布评论