Angular 递归组件数据引用问题
我正在尝试构建一个类别选择器组件,该组件获得一个类别树作为第一手输入,如下所示:Angular 递归组件数据引用问题,angular,Angular,我正在尝试构建一个类别选择器组件,该组件获得一个类别树作为第一手输入,如下所示: mockData: Category[] = [ { id: 1, name: 'main cat1', children: [ { id: 3, name: 'sub cat1', children: []}, { id: 4, name: 'sub kat2', children: []} ]}, { id: 2, name: 'main cat2', ch
mockData: Category[] = [
{ id: 1, name: 'main cat1', children: [
{ id: 3, name: 'sub cat1', children: []},
{ id: 4, name: 'sub kat2', children: []}
]},
{ id: 2, name: 'main cat2', children: [
{ id: 5, name: 'sub cat5', children: []},
]},
]
模板:
该组件在ngFor
中显示主要类别。如果选择了一个类别,它会手动将#tpl标记的模板插入到#vc视图容器中。这是对我的假设的一次尝试,我认为这会解决问题
<mat-chip-list aria-label="Category selection" [multiple]="false">
<mat-chip *ngFor="let chip of data"
[selected]="chip.id === selectedCategory?.id"
(click)="clickChip($event, chip)">{{ chip.name }}</mat-chip>
</mat-chip-list>
<ng-container #vc></ng-container>
<ng-template #tpl>
<span class="divider"> / </span>
<category [data]="copyOFChildren"
(selected)="emitSelected($event)"
></category>
</ng-template>
{{chip.name}
/
组成部分:
export class CategorySelectorComponent implements AfterViewInit, OnInit {
@Input() data: Category[];
@Output() selected: EventEmitter<Category> = new EventEmitter();
selectedCategory: Category;
copyOFChildren: Category[];
@ViewChild("vc", {read: ViewContainerRef, static: true}) vc: ViewContainerRef;
@ViewChild('tpl', {static:true}) tpl: TemplateRef<any>;
childViewRef: ViewRef;
ngAfterViewInit(){
this.childViewRef = this.tpl.createEmbeddedView(null);
}
clickChip(event, category) {
this.removeChildView();
this.selectedCategory = (this.selectedCategory && this.selectedCategory.id === category.id) ? null : {...category};
this.selected.emit(this.selectedCategory);
this.insertChildView();
}
emitSelected(category: Category | null):void {
if (category) {
this.selected.emit(category)
} else {
this.selected.emit(this.selectedCategory)
}
}
insertChildView(){
if (this.selectedCategory && this.selectedCategory.children.length) {
this.copyOFChildren = [ ...this.selectedCategory.children ];
this.vc.insert(this.childViewRef);
}
}
removeChildView(){
this.copyOFChildren = undefined;
this.vc.detach();
console.log('detach')
}
}
导出类CategorySelectorComponent在ViewInit、OnInit之后实现{
@输入()数据:类别[];
@选择输出():EventEmitter=新的EventEmitter();
selectedCategory:类别;
儿童:类别[];
@ViewChild(“vc”,{read:ViewContainerRef,static:true})vc:ViewContainerRef;
@ViewChild('tpl',{static:true})tpl:TemplateRef同时找到了一个解决方案
问题是我使递归元素的组件保持活动状态,因此它保留在内存中,因为它在模板中的形式如下:
<ng-template #tpl>
<span class="divider"> / </span>
<category [data]="copyOFChildren"
(selected)="emitSelected($event)"
></category>
</ng-template>
/
解决方案:
我没有使用
而是使用ComponentFactoryResolver
手动创建子组件并将输入和输出绑定到它
查看演示: