我一直在尝试动态创建组件并将其附加到文档标记。我一直很难弄清楚如何选择正文的ViewContainterRef,所以我可以使用ComponentFactoryResolver添加一个新的组件。
我尝试使用下面的代码获取对body容器的引用,但它不起作用。有谁知道怎么做?谢谢!
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);
}
}
答案 0 :(得分:6)
Angular2材料团队正在为工具提示和其他动态组件执行类似的操作,视图可能位于当前容器引用之外。
这是班级:https://github.com/angular/material2/blob/master/src/lib/core/portal/dom-portal-host.ts 他们在做什么:
首先注入一堆有用的类:
constructor(
private _viewRef: ViewContainerRef,
private _hostDomElement: Element,
private _componentFactoryResolver: ComponentFactoryResolver,
private _appRef: ApplicationRef,
private _defaultInjector: Injector) {
}
然后: 在当前viewContainerRef中创建组件,在您的情况下是您的模态。
ngOnInit() {
// Calls the factory to crate a brand new instance
let componentFactory = this._componentFactoryResolver.resolveComponentFactory(ModalComponent);
let componentRef = this._viewRef.createComponent(componentFactory);
}
然后将其附加到appRef
(this._appRef as any).attachView(componentRef.hostView);
this.setDisposeFn(() => {
(this._appRef as any).detachView(componentRef.hostView);
componentRef.destroy();
});
我从来没有这样做过,所以你可能需要付出一些努力,但我认为这就是方法。
答案 1 :(得分:2)
我通过单独的服务解决了这个问题:
afr[dafr['b'].apply(lambda x: 2 in x)]
然后在你的组件中:
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();
}
}