问题描述
假设我有一个接口(或实际组件)ListItemRenderer
和一个实现该接口(或扩展基本组件)的组件MyRendererComponent
Let's say I got an interface (or an actual component) ListItemRenderer
and a component MyRendererComponent
that implements that interface (or extends the base component)
@Component({
selector: 'my-renderer',
template: '<div>My renderer</div>'
})
export class MyRendererComponent implements ListItemRenderer {
...
}
我想将此具体实现传递给另一个组件,例如
I'd like to pass this concrete implementation to another component, e.g.
@Component({
selector: 'my-list',
template: `
<ul [renderer]="renderer" [items]="items">
<li *ngFor="let item of items">
<!-- what goes here? -->
</li>
</ul>
`
})
export class MyList {
@Input() renderer: ListItemRenderer;
@Input() items: any[];
...
}
很明显,父组件将具有类型为ListItemRenderer
的公共属性renderer
.问题是,我该如何在<li>
中使用该组件(请参见上面的"这是怎么回事?")?
Obviously, the parent component would have a public property renderer
of type ListItemRenderer
. The question is, how do I go about using that component in my <li>
(see "what goes here?" above)?
推荐答案
要使用*ngFor
动态添加组件,您需要类似dcl-wrapper
的内容,该内容在(不推荐使用DynamicComponentLoader
,而推荐使用ViewContainerRef.createComponent()
,但我没有尝试为包装器组件引入另一个名称.)
To add components dynamically using *ngFor
you need something like the dcl-wrapper
explained in https://stackoverflow.com/a/36325468/217408 (DynamicComponentLoader
is deprecated in favor of ViewContainerRef.createComponent()
but I didn't try to introduce another name for the wrapper component.)
@Component({
selector: '[dcl-wrapper]', // changed selector in order to be used with `<li>`
template: `<div #target></div>`
})
export class DclWrapper {
@ViewChild('target', {read: ViewContainerRef}) target;
@Input() type;
cmpRef:ComponentRef;
private isViewInitialized:boolean = false;
constructor(private resolver: ComponentResolver) {}
updateComponent() {
if(!this.isViewInitialized) {
return;
}
if(this.cmpRef) {
this.cmpRef.destroy();
}
this.resolver.resolveComponent(this.type).then((factory:ComponentFactory<any>) => {
this.cmpRef = this.target.createComponent(factory)
});
}
ngOnChanges() {
this.updateComponent();
}
ngAfterViewInit() {
this.isViewInitialized = true;
this.updateComponent();
}
ngOnDestroy() {
if(this.cmpRef) {
this.cmpRef.destroy();
}
}
}
并像使用它
@Component({
selector: 'my-list',
template: `
<ul [items]="items">
<li *ngFor="let item of items" dcl-wrapper [type]="renderer" ></li>
</ul>
`
})
export class MyList {
@Input() renderer: ListItemRenderer;
@Input() items: any[];
...
}
这篇关于如何渲染实现接口的组件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!