You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 17中@ContentChildren结合指令选择器无法获取内容问题

问题

在Angular 17.2独立组件项目中,尝试通过自定义指令枚举<ng-template>元素,参考旧版示例代码后,@ContentChildren始终返回空数组。

相关代码如下:

自定义指令 TableColumnDirective

import { Directive, TemplateRef, Input } from '@angular/core';

@Directive({
  selector: '[tableColumn]'
})
export class TableColumnDirective 
{
  constructor(public readonly template: TemplateRef<any>) { }
  @Input('tableColumn') columnName: string = '';
}

父组件模板 app.component.html

<my-table>
  <ng-template tableColumn="firstname" let-firstname>
    <h1>this template is for column firstName</h1>
 </ng-template>
 <ng-template tableColumn="lastName" let-lastname>
    <h1>this template is for column lastName</h1>
 </ng-template>
</my-table>

子组件 TestComponent(选择器my-table)

import { AfterContentInit, Component, ContentChildren, QueryList } from '@angular/core';
import { TableColumnDirective } from '../table-column.directive';

@Component({
  standalone: true,
  selector: 'my-table',
  templateUrl: './test-component.html',
  styleUrl: './test-component.scss'
})
export class TestComponent implements AfterContentInit {

  @ContentChildren(TableColumnDirective) columnList!: QueryList<TableColumnDirective>;
  
  ngAfterContentInit(){
    console.log('column template list');
    console.log(this.columnList.toArray());
  }
}

预期ngAfterContentInit中columnList能获取到带tableColumn指令的模板,但实际输出空数组。背景是修复已停止维护的ngx-property-grid组件,该组件依赖此技术。

解决方法

问题核心是Angular 17独立组件需要显式导入用到的指令,旧版模块式项目的逻辑不再适用,具体修复步骤:

  • 给TableColumnDirective添加独立标记
    Angular 17中,独立组件只能导入独立的指令/管道/组件,需在指令元数据中声明standalone: true:

    @Directive({
      selector: '[tableColumn]',
      standalone: true
    })
    export class TableColumnDirective 
    {
      constructor(public readonly template: TemplateRef<any>) { }
      @Input('tableColumn') columnName: string = '';
    }
    
  • 在TestComponent的imports中导入指令
    独立组件不会自动识别外部指令,必须在组件元数据的imports数组里声明要使用的指令:

    @Component({
      standalone: true,
      selector: 'my-table',
      templateUrl: './test-component.html',
      styleUrl: './test-component.scss',
      imports: [TableColumnDirective]
    })
    export class TestComponent implements AfterContentInit {
      // ... 原有代码不变
    }
    

完成以上修改后,ngAfterContentInit就能正确获取到所有带有tableColumn指令的模板实例。

内容的提问来源于stack exchange,提问作者Phil Jollans

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 18:07:53