Angular 9+: 嵌套的 ng-content 和 ContentChildren
Angular 9+: nested ng-content and ContentChildren
我正在尝试使用 ContentChildren 捕获外部 ng-content 的内容,但没有成功。
这是代码:
app.component.html:
<app-table-wrapper>
<app-column></app-column>
<app-column></app-column>
<app-column></app-column>
</app-table-wrapper>
table-包装器:
@Component({
selector: 'app-table-wrapper',
template: `<p>table-wrapper works!</p>
<app-hyd-table>
<ng-content></ng-content>
</app-hyd-table> `,
})
export class TableWrapperComponent implements OnInit {
@ViewChild(HydTableComponent, { static: true }) _hydTable: HydTableComponent;
@ContentChildren(ColumnComponent, { descendants: true }) columns: QueryList<
ColumnComponent
>;
constructor() {}
ngOnInit(): void {
console.log('table wrapper - ngOnInit');
}
ngAfterContentInit(): void {
console.log('table wrapper - ngAfterContentInit');
console.log({ columns: this.columns });
}
ngAfterViewInit(): void {
console.log('table wrapper - ngAfterViewInit');
this._hydTable.columns = this.columns; // <--- Manual override
}
}
table:
@Component({
selector: 'app-hyd-table',
template: `<p>hyd-table works!</p>
<ng-content></ng-content>
<div *ngFor="let col of columns; let i = index">Column {{ i }}</div>
`,
})
export class HydTableComponent implements OnInit {
@ContentChildren(ColumnComponent) columns: QueryList<ColumnComponent>; // <-- this is empty
constructor() {}
ngOnInit(): void {
console.log("table - ngOnInit");
}
ngAfterContentInit(): void {
console.log("table - ngAfterContentInit");
console.log({ columns: this.columns });
}
ngAfterViewInit(): void {
console.log("table - ngAfterViewInit");
}
}
在 table 组件中,QueryList 是空的,我必须在 ngAfterViewInit 中手动从 table-wrapper 组件设置它,否则 table 组件中的 *ngFor不会渲染任何东西。
所以我的问题是:如何将包装器组件的 ng-content“转发”到内部组件的 ContentChildren? HTML 甚至在内部组件内部呈现,只是 ContentChildren 无法在其模板中获取列。
在 Google 中找到合适的关键字后,我发现这个问题已经开放了 3 年多了,但仍然没有解决方案:
https://github.com/angular/angular/issues/16299
看来我得用肮脏的方式来做。
我正在尝试使用 ContentChildren 捕获外部 ng-content 的内容,但没有成功。 这是代码: app.component.html:
<app-table-wrapper>
<app-column></app-column>
<app-column></app-column>
<app-column></app-column>
</app-table-wrapper>
table-包装器:
@Component({
selector: 'app-table-wrapper',
template: `<p>table-wrapper works!</p>
<app-hyd-table>
<ng-content></ng-content>
</app-hyd-table> `,
})
export class TableWrapperComponent implements OnInit {
@ViewChild(HydTableComponent, { static: true }) _hydTable: HydTableComponent;
@ContentChildren(ColumnComponent, { descendants: true }) columns: QueryList<
ColumnComponent
>;
constructor() {}
ngOnInit(): void {
console.log('table wrapper - ngOnInit');
}
ngAfterContentInit(): void {
console.log('table wrapper - ngAfterContentInit');
console.log({ columns: this.columns });
}
ngAfterViewInit(): void {
console.log('table wrapper - ngAfterViewInit');
this._hydTable.columns = this.columns; // <--- Manual override
}
}
table:
@Component({
selector: 'app-hyd-table',
template: `<p>hyd-table works!</p>
<ng-content></ng-content>
<div *ngFor="let col of columns; let i = index">Column {{ i }}</div>
`,
})
export class HydTableComponent implements OnInit {
@ContentChildren(ColumnComponent) columns: QueryList<ColumnComponent>; // <-- this is empty
constructor() {}
ngOnInit(): void {
console.log("table - ngOnInit");
}
ngAfterContentInit(): void {
console.log("table - ngAfterContentInit");
console.log({ columns: this.columns });
}
ngAfterViewInit(): void {
console.log("table - ngAfterViewInit");
}
}
在 table 组件中,QueryList 是空的,我必须在 ngAfterViewInit 中手动从 table-wrapper 组件设置它,否则 table 组件中的 *ngFor不会渲染任何东西。
所以我的问题是:如何将包装器组件的 ng-content“转发”到内部组件的 ContentChildren? HTML 甚至在内部组件内部呈现,只是 ContentChildren 无法在其模板中获取列。
在 Google 中找到合适的关键字后,我发现这个问题已经开放了 3 年多了,但仍然没有解决方案: https://github.com/angular/angular/issues/16299 看来我得用肮脏的方式来做。