Demiro-FE-Architect
Demiro-FE-Architect

Reputation: 3740

Angular2: Passing multi-slot transcluded content to children components as parameters

I am having and article component prefixed with b-...

<b-article>

and inside I have some custom elements

  1. b-title
  2. b-photo
  3. b-summary

using like this:

<b-article-item>
    <b-title>My Article Title</b-title>
    <b-photo>http://placehold.it/1280X720</b-photo>
    <b-summary>some new content</b-summary>
</b-article-item>

so, if I wouldn't have some more components in the article-item (and no photo) then it would be fairly easy:

<div class="article">
    <h2><ng-content select="b-title"></ng-content></h2>
    <p class="summary"><ng-content select="b-summary"></ng-content></p>
</div>

but, already it get's complicated with the photo, where the src is as attribute

<div class="article">
    <img src="{{photo}}">
    <h2><ng-content select="b-title"></ng-content></h2>
    <p class="summary"><ng-content select="b-summary"></ng-content></p>
</div>

My structure is a bit more complicated, but doesn't make much difference in logic....

<div class="article">
    <b-thumbnail
        [photo] = "photo"
        [isResponsive] = "true"
    ></b-thumbnail>
    <b-excerpt
        [title]="title"
        [summary]="summary"
    ></b-excerpt>
</div>

HOW, do I get the b-photo's inner HTML as article-item's property...

Worth mentioning that b-photo, b-title and b-summary are not actual components, just custom tags (using CUSTOM_ELEMENTS_SCHEMA to allow them)

Any ideas?

I tried to put this in the article item constructor

constructor(private el:ElementRef){
    let ref = this.el.nativeElement;

    let photos = ref.getElementsByTagName('b-photo');

    if(photos.length > 0){
        this.photo = photos[0].innerHTML;
    }
}

Don't get an ewxpected result, the length is 0

Upvotes: 2

Views: 720

Answers (1)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657466

It's definitely not how it should be done in Angular2 because it requires reading from the DOM and causes issues when server-side rendering and WebWorker features should be used.

This should work though:

<div class="article">
    <span #wrapper><ng-content select="b-photo"></ng-content></span>
</div>
export class BArticleItem {
  @ViewChild('wrapper') wrapper:ElementRef;

  ngAfterContentInit() {
    this.photo = this.wrapper.nativeElement.querySelector('b-photo').innerHTML;
  }
}

Upvotes: 1

Related Questions