gpt4 book ai didi

Angular2 - 如何动态创建组件并附加到主体的 View 容器

转载 作者:行者123 更新时间:2023-12-01 23:15:47 29 4
gpt4 key购买 nike

我一直在尝试动态创建一个组件并将其附加到文档标签。我一直很难弄清楚如何选择正文的 ViewContainterRef,所以我可以使用 ComponentFactoryResolver 附加一个新组件。

我尝试使用下面的代码获取对主体容器的引用,但它不起作用。有人知道怎么做吗?谢谢!

import {
Component,
ComponentRef,
ApplicationRef,
Injector,
Input,
ViewContainerRef,
ComponentFactoryResolver,
ViewChild,
OnInit,
OnDestroy
} from '@angular/core';

import {
ModalComponent
} from './modal.component';

@Component({
selector: 'my-modal'
})
export class MyModalComponent {

private _bodyRef: ViewContainerRef;


constructor(private resolver: ComponentFactoryResolver, private app: ApplicationRef) {

// Does not work!
this._bodyRef = app['_rootComponents'][0]['_hostElement'].vcRef;

}


ngOnInit() {

// Calls the factory to crate a brand new instance
let componentFactory = this.resolver.resolveComponentFactory(ModalComponent);
this._bodyRef.createComponent(componentFactory);


}
}

最佳答案

我用单独的服务解决了这个问题:

import {
Injectable,
ComponentFactoryResolver,
ApplicationRef,
Injector,
EmbeddedViewRef,
ComponentRef
} from '@angular/core';

@Injectable()
export class DOMService {

constructor(
private componentFactoryResolver: ComponentFactoryResolver,
private applicationRef: ApplicationRef,
private injector: Injector,
) {}

appendComponentToBody(component: any) {
//create a component reference
const componentRef = this.componentFactoryResolver.resolveComponentFactory(component)
.create(this.injector);

// attach component to the appRef so that so that it will be dirty checked.
this.applicationRef.attachView(componentRef.hostView);

// get DOM element from component
const domElem = (componentRef.hostView as EmbeddedViewRef < any > )
.rootNodes[0] as HTMLElement;

document.body.appendChild(domElem);

return componentRef;
}

removeComponentFromBody(componentRef: ComponentRef < any > ) {
this.applicationRef.detachView(componentRef.hostView);
componentRef.destroy();
}
}

然后在你的组件中:

import {
Component,
AfterContentInit
} from '@angular/core';
import {
ComponentToInject
} from 'path/to/component';
import {
DOMService
} from 'path/to/service';

@Component({
selector: 'my-component',
template: '....'
})
export class MyComponent implements AfterContentInit {

constructor(
private DOMService: DOMService,
) {}

ngAfterContentInit() {
// to prevent ExpressionChangedAfterItHasBeenCheckedError
setTimeout(() => {
const cmp = this.DOMService.appendComponentToBody(ComponentToInject);

// if you need to get access to input of injected component. Let's say ComponentToInject has public property title
const instance = cmp.instance;
instance.title = 'Some title';

// if you need to get access to output of injected component. Let's say ComponentToInject assings EventEmitter to onClick property
instance.onClick.subscribe(() => { // do somethis })
});
}

}

关于Angular2 - 如何动态创建组件并附加到主体的 View 容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41193852/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com