noxi雑記

.NET、Angularまわりの小ネタブログ

ng-content、ContentChild、ContentChildrenはネストしたコンポーネントの中身まで見てくれない

Angularでは @ContentChild@ContentChildren を使用して <ng-content> の中で入れ子にした子要素を取得することができます。また <ng-content>セレクターを使用して個別の子要素を取得できます。しかしこれには制約があり、 自分の子要素として直接設置された要素 のみが対象で、子要素に入れ子にした孫要素の中は取得されません。これはバグでは無く意図した挙動らしいです。

It is the expected behavior, you can only query direct children.

The rationale being that you might not know about inner component implementation and should not be affected by them.

https://github.com/angular/angular/issues/10121#issuecomment-233198718

取得できるパターン

親要素の中に直接入れた子要素は表示される(hogefuga が表示される)。

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    <parent>
      <child>hoge</child>
      <child>fuga</child>
    </parent>
  `,
  styles: []
})
export class AppComponent {
}

@Component({
  selector: 'child',
  template: `<ng-content></ng-content>`,
  styles: []
})
export class Child {
}

@Component({
  selector: 'parent',
  template: `<ng-content select="child"></ng-content>`,
  styles: []
})
export class Parent {
}

f:id:noxi515:20190528200142p:plain

取得できないパターン

親要素をラップしたコンポーネントの中に子要素を入れると何も表示されない。

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    <wrapper>
      <child>hoge</child>
      <child>fuga</child>
    </wrapper>
  `,
  styles: []
})
export class AppComponent {
}

@Component({
  selector: 'child',
  template: `<ng-content></ng-content>`,
  styles: []
})
export class Child {
}

@Component({
  selector: 'parent',
  template: `<ng-content select="child"></ng-content>`,
  styles: []
})
export class Parent {
}

@Component({
  selector: 'wrapper',
  template: `<parent><ng-content></ng-content></parent>`,
  styles: []
})
export class Wrapper {
}

f:id:noxi515:20190528200210p:plain