我将动态地将组件组合到服务中的另一个组件,首先,在服务工厂中同时将两个组件和我创建的组件都可以访问ViewContainer。但是无法创建组件!
服务:
@Injectable({
providedIn: 'root'
})
export class ModalService {
componentRef: ComponentRef<ModalTemplateComponent>;
constructor(private _modalService: BsModalService,
private resolver: ComponentFactoryResolver,
private injector: Injector) {
}
open(componentType: any) {
const contentFactory = this.resolver
.resolveComponentFactory(componentType);
const templateFactory = this.resolver
.resolveComponentFactory(ModalTemplateComponent);
const componentRef = templateFactory.create(this.injector);
componentRef.instance.container.createComponent(contentFactory);
this._modalService.show(componentRef.componentType, {class: 'modal-lg', initialState: {data: {test:true}});
}
}
组件:
selector: 'lib-modal-template',
template: `
<h1>{{title}}</h1>
<ng-container #container>
</ng-container>
`,
styleUrls: ['./modal-template.component.css']
})
export class ModalTemplateComponent implements OnInit {
title:string;
@ViewChild('container', {read: ViewContainerRef, static: true}) container: ViewContainerRef;
}
示例:
this._modalService.open(NewUserForm,...);
答案 0 :(得分:3)
首先,此行将创建ModalTemplateComponent
而不是componentRef
的新实例,因此您不在同一实例上工作。
this._modalService.show(componentRef.componentType, {class: 'modal-lg', initialState: {data: {test:true}}});
我做了一些调整(使用ngComponentOutlet
),它将按您的预期工作:
ModalService
@Injectable({
providedIn: 'root'
})
export class ModalService {
constructor(private _modalService: BsModalService,
private resolver: ComponentFactoryResolver,
private injector: Injector) {
}
open(componentType: any) {
const ref = this._modalService.show(ModalTemplateComponent, {class: 'modal-lg', initialState: {data: {test:true}}});
(ref.content as ModalTemplateComponent).componentType = componentType;
}
}
ModalTemplateComponent
@Component({
selector: 'app-modal-template',
template: `
<h1>{{title}}</h1>
<ng-container *ngComponentOutlet="componentType">
</ng-container>
`,
styleUrls: ['./modal-template.component.css']
})
export class ModalTemplateComponent implements OnInit {
title: string = 'modal-template';
@Input() componentType: any;
constructor() { }
ngOnInit() {
}
}
在线演示:https://stackblitz.com/edit/angular-1srnej?file=src%2Fapp%2Fmodal.service.ts
==============================
如果要使用动态组件实例,我们可以使用以下解决方案:
ModalTemplateComponent
@Component({
selector: 'app-modal-template',
template: `
<h1>{{title}}</h1>
<ng-container #container>
</ng-container>
`,
styleUrls: ['./modal-template.component.css']
})
export class ModalTemplateComponent implements OnInit, OnDestroy {
title: string = 'modal-template';
component: any;
componentRef: ComponentRef<any>;
@Input() set componentType(c: any) {
this.component = c;
this.renderContent();
}
@ViewChild('container', {
read: ViewContainerRef,
static: true
}) container: ViewContainerRef;
constructor() { }
ngOnInit() {
}
renderContent() {
this.container.clear();
const injector = this.container.injector;
const cfr = injector.get(ComponentFactoryResolver);
const componentFactory = cfr.resolveComponentFactory(this.component);
const componentRef = this.container.createComponent<any>(componentFactory);
componentRef.instance.content = 'content from ' + this.title;
this.componentRef = componentRef;
}
ngOnDestroy() {
if (this.componentRef) {
this.componentRef.destroy();
}
}
}
AlertContentComponent
export class AlertContentComponent implements OnInit {
@Input() content = '';
constructor() { }
ngOnInit() {
}
}