简体   繁体   中英

How do you render ContentChildren elements in an ng-template?

Given a component, I wish to wrap the rendered child elements in it.

How is this possible in angular2?

For example, I have this component:

export class InnerTestComponent implements OnInit {
  @ContentChildren('link') contents: QueryList<ElementRef>;
}

and this template:

<div>
  <h3>Children test: {{ contents.length }} to render</h3>
  <div *ngFor="let child of contents">
    <ng-container *ngTemplateOutlet="someTemplateName; context: {child: child}">
    </ng-container>
  </div>
</div>

<ng-template #someTemplateName let-child="child">
  <h3>Child</h3>
  <div>
    {{ child }}
  </div>
</ng-template>

And when I call:

<templates-inner-test>
  <a #link href="#">Test1</a>
  <a #link href="#">Test2</a>
</templates-inner-test>

I get:

<templates-inner-test>
<div>
  <h3>Children test: 2 to render</h3>
  <h3>Child</h3>
  <div>
    [object Object] <--- WRONG
  </div>
  </div><div>
  <h3>Child</h3>
  <div>
    [object Object] <--- WRONG
  </div>
  </div>
</div>
</templates-inner-test>

When what I want is:

<h3>Child</h3>
<div>
  <a href="#">Test1</a>
</div>
<h3>Child</h3>
<div>
  <a href="#">Test2</a>
</div>

I appreciate rendering an ElementRef in {{ ... }} simply executes toString() on it, but what should I be doing instead?

I would like to also specifically point out that the solutions floating around in various places to use the <ng-content select="child"></ng-content> flat out don't work. That just renders an empty <div> .

Since contents is a list ElementRef , and you are looping through it, child is a ElementRef, so you probably need to use child.nativeElement.innerHTML .

But you definitely need to use DomSanitizer here, with it you could probably do the following

import { Pipe, PipeTransform } from "@angular/core";
import { DomSanitizer } from "@angular/platform-browser";

@Pipe({name: 'safeHtml'})
export class SafeHtml implements PipeTransform  {
    constructor(private sanitizer:DomSanitizer){}
    transform(style) {
        return this.sanitizer.bypassSecurityTrustHtml(style);   
    }
}

Then you could

<ng-template #someTemplateName let-child="child">
    <h3>Child</h3>
    <div [innerHTML]="child.nativeElement.innerHTML | safeHtml" ></div>
</ng-template>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM