【问题标题】:Angular4 custom Structural Directive causing Component to not be found by @ContentChildren()Angular4自定义结构指令导致@ContentChildren()找不到组件
【发布时间】:2017-07-21 10:30:57
【问题描述】:

我有 3 个嵌套组件形成一个通用网格组件:MyGridMyRowMyColumn,使用时会呈现以下形状。我遇到的问题是,每当我将*myRowItem 指令附加到my-row 组件时,位于MyGrid 中的一些@ContentChildren(MyRowComponent) 找不到该组件,而当我不使用*myRowItem 指令时,查询找到所述组件。该指令似乎以某种方式掩盖了内容。

我知道通过 Angular 的脱糖,*myRowItem 指令被翻译成 <ng-template>...</ng-template> 并排序,但我在这里遗漏了什么吗?

用法

<my-grid [data-source]="dataSource">
    <my-row *myRowItem="let item">
        <my-column column-header="Person">
            {{item.name}}
        </my-column>

        <my-column column-header="Age">
            {{item.age}}
        </my-column>

        <my-column column-header="Car">
            {{item.car}}
        </my-column>
    </my-row>
</my-grid>

MyGrid 是负责渲染整个表格的组件。 MyRow 是另一个组件,它将列组合在一起,定义如下:

MyRow.ts

@Component({
  selector: 'my-row',
  template: `<ng-content></ng-content>`,
})
export class MyRowComponent 
{

  @ContentChildren(MyColumnComponent)
  public columns: QueryList<MyColumnComponent>;

  /**
   * Class constructor
   */
  constructor()
  {
  }
}

MyColumn 用于将模板中继到网格(并且为了便于阅读,我已经截断了一些附加功能)。

MyColumn.ts

@Component({
   selector: 'my-column',
   template: `<ng-container *ngIf="..."><ng-content></ng-content></ng-container>`
})
export class CoreColumnComponent
{

  ...

  constructor()
  {
  }
}

*myRowItem 用于创建一个上下文,在该上下文中使用$implicit 我可以将值通过管道传递到位于MyGrid 的*ngFor。

MyRowItem.ts

@Directive({
  selector: '[myRowItem]',
})
export class MyRowItemDirective
{

  constructor()
  {
  }
}

MyGrid.ts

@Component({
  selector: 'my-grid',
  templateUrl: 'my-grid.html'
})
export class MyGridComponent implements AfterViewInit
{

   ...

  /**
   * My item directive (IS BEING POPULATED AND I CAN RENDER THROUGH IT)
   */
  @ContentChild(MyRowItemDirective, { read: TemplateRef })
  public rowTemplate: TemplateRef<MyRowItemDirective>;

  /**
 * My row component (IS NOT BEING POPULATED)
 */
  @ContentChild(MyRowComponent)
  public rowDefinition: MyRowComponent;


  constructor()
  {
  }

  ngAfterViewInit(): void
  {
    let x = this.rowDefinitions; // BEING EMPTY HERE
  }

}

MyGrid.html

<table>
  <tbody>
    <ng-container *ngFor="let row of dataSource" [ngTemplateOutlet]="rowTemplate" [ngOutletContext]="{$implicit: row}"></ng-container>
  </tbody>
</table>

【问题讨论】:

  • 您是否尝试过使用 setter 或订阅 QueryList 的更改?在您的结构指令中调用 createEmbeddedView 之前,我们不会填充 ContentChild/ContentChildren
  • 有趣,你能创建一个 plunker 吗?

标签: angular


【解决方案1】:

代码中的列选择器是“core-column”应该是“my-column”?

【讨论】:

  • 你说得对,将项目从项目重命名为示例时出现错误。
猜你喜欢
  • 2020-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-21
  • 2020-07-23
  • 2020-01-01
  • 2019-02-21
  • 1970-01-01
相关资源
最近更新 更多