Reputation: 236
I am trying to get multiple template refs using @ContentChild
but first one is displayed.
modal.component.html
<div class="ac-modal">
<ng-container [ngTemplateOutlet]="modalHeader"></ng-container>
<ng-container [ngTemplateOutlet]="modalBody"></ng-container>
<ng-container [ngTemplateOutlet]="modalFooter"></ng-container>
</div>
modal.component.ts
@Component({
selector: 'ac-modal',
templateUrl: './modal.component.html',
styleUrls: ['./modal.component.css']
})
export class ModalComponent implements OnInit, OnDestroy, AfterContentInit {
@ContentChild(TemplateRef) modalHeader: TemplateRef<void>;
@ContentChild(TemplateRef) modalBody: TemplateRef<void>;
@ContentChild(TemplateRef) modalFooter: TemplateRef<void>;
ngAfterContentInit() {
console.log("HEADER: ", this.modalHeader);
console.log("body: ", this.modalBody);
console.log("footer: ", this.modalFooter);
}
}
app.component.html
<ac-modal>
<ac-modal-header *acModalHeader></ac-modal-header>
<ac-modal-body *acModalBody></ac-modal-body>
<ac-modal-footer *acModalFooter></ac-modal-footer>
</ac-modal>
modal-footer.directive.ts
@Directive({
selector: '[acModalFooter]'
})
export class ModalFooterDirective {
constructor(tempalteRef: TemplateRef<void>,
modalComponent: ModalComponent) {
modalComponent.modalFooter = tempalteRef;
}
}
modal-header.directive.ts
@Directive({
selector: '[acModalHeader]'
})
export class ModalFooterDirective {
constructor(tempalteRef: TemplateRef<void>,
modalComponent: ModalComponent) {
modalComponent.modalHeader = tempalteRef;
}
}
modal-body.directive.ts
@Directive({
selector: '[acModalBody]'
})
export class ModalFooterDirective {
constructor(tempalteRef: TemplateRef<void>,
modalComponent: ModalComponent) {
modalComponent.modalBody = tempalteRef;
}
}
Output
modal-header works!
modal-header works!
modal-header works!
Whichever tag I put first in modal.component.html
inside <ac-modal>
component gets displayed 3 times. 3 times because I have 3 <ng-container>
in modal.component.html
but I am not able to figure out why this is happening because I am passing different templaterefs for each.
Upvotes: 0
Views: 3046
Reputation: 1661
You're querying for TemplateRef
, so Angular will always give you the first one. You want to target the specific directives you need:
@ContentChild(ModalHeaderDirective, {read: TemplateRef}) modalHeader: TemplateRef<void>;
@ContentChild(ModalBodyDirective, {read: TemplateRef}) modalBody: TemplateRef<void>;
@ContentChild(ModalFooterDirective, {read: TemplateRef}) modalFooter: TemplateRef<void>;
If you do this, you don't even need to inject ModalComponent
in the directives anymore, the @ContentChild
is enough to get the TemplateRefs
.
Upvotes: 1
Reputation: 236
Because ContentChild
only gets first matching selector
change modal.component.ts to
modalHeader: TemplateRef<void>;
modalBody: TemplateRef<void>;
modalFooter: TemplateRef<void>;
@ContentChildren(TemplateRef) templateRefs;
ngAfterContentInit() {
this.templateRefs.forEach((template: TemplateRef<void>) => {
if (template === this.modalHeader) {
//here you can do stuff for ModalHeaderComponent
}
});
}
Upvotes: 0