8

I am trying to define some html in my parent component that can be passed to the child component. Is this possible? I have tried a couple of things like this: How to pass an expression to a component as an input in Angular2?, but I did not have any luck. Maybe my syntax was wrong. I was a little confused with the let. Appreciate all the help and any explanations to help me understand this better.

@Component({
    selector: 'app-my-parent',
    template: `
    <div>other parent html</div>
    <app-my-child [property]="value">
        <ng-template #someTemplate">value.first</ng-template>
    </app-my-child>
    <app-my-child [property]="value">
        <ng-template #someTemplate">value.second</ng-template>
    </app-my-child>
    `
})
export class MyParent {
}
@Component({
    selector: 'app-my-child',
    template: `
    <div>other child html</div>
    how do I access the template from here? Is there a way to do binding with templates? 

})
export class MyChild {
      @Input() property;
}
gonzo
  • 2,103
  • 1
  • 15
  • 27
  • Are you trying to access the exact same template in both the parent and the child? If so, just create a separate file and use templateurl instead of template. – Notmfb Nov 16 '17 at 16:45
  • No, I dont want the same template for both the parent and the child. There is other html, I don't want to replace the whole template. – gonzo Nov 16 '17 at 16:46

2 Answers2

16

You need to add an ng-content tag to your child component so angular knows it's supposed to transclude content and where to put the content:

@Component({
    selector: 'app-my-child',
    template: `
    <div>other child html</div>
    <ng-content></ng-content>
    `
})
export class MyChild {
}

then you need to remove the ng-template tags, because that tells angular to actually not render these things at all, because they're templates meant to be used elsewhere

Using it in the parent is super simple:

<app-my-child>Anything put between these component tags will be transcluded to the ng-content tag</app-my-child>
bryan60
  • 28,215
  • 4
  • 48
  • 65
  • So how does the child `ng-content` know what element to look for in the parent. Or how are they linked? – gonzo Nov 16 '17 at 16:55
  • if you only have one ng-content, anything inside the componente tags gets transcluded into that zone. so All of this will appear between the ng-content tags in my child component, but if you want multiple ng-content tags in the same component, then you need to use selectors to indicate which item goes where. But it seems you don't have that issue here. – bryan60 Nov 16 '17 at 16:57
  • What if i introduce a new component. So lets say it is a table and a row. I want to include some row html but access it from the table template. I will create a new question and link it here. I understand the concept better with your explanation. Thank you. – gonzo Nov 16 '17 at 17:02
  • I think I get what you're saying, but what you're talking about is a much more advanced topic, pretty much reserved for building angular libraries for distribution or heavy re use across applications. If this is your goal, I think angular university has a good course on it. – bryan60 Nov 16 '17 at 17:05
  • 1
    here's a link to their article about it: https://blog.angular-university.io/angular-ng-template-ng-container-ngtemplateoutlet/ – bryan60 Nov 16 '17 at 17:08
6

As @bryan60 pointed out, the child template needs an <ng-content>. In the parent, everything you put within the child selector will be displayed at the ng-content location immediately before the AfterContentInit() lifecycle hook executes:

Parent component template:

<child-cmp>
  <p>This will appear within ng-content of ChildComponent</p>
</child-cmp>

Child component template:

  <h2>I am ChildComponent</h2>
  <ng-content></ng-content>

Live demo

BeetleJuice
  • 39,516
  • 19
  • 105
  • 165