Can the class itself see transcluded content?

By : KRyan
Source: Stackoverflow.com
Question!

So in Angular2, the following is pretty simple:

@Component({
  selector: 'some',
  properties: ['header']
})
@View({
  template: `
    <div>
      <h2>{{ getFormattedHeader() }}</h2>
      <p><content></content></p>
    </div>
  `
})
class SomeComponent {
  header: string;

  getFormattedHeader() {
    return this.header + '!';
  }
}
<some header="Header Text">Content</some>

And you get this:

<div>
  <h2>Header Text!</h2>
  <p>Content</p>
</div>

But what if I wanted to apply formatting on the content? Can I write a getFormattedContent() function, and if so what do I replace this.header with?

For that matter, I could have chosen to use format(header) in the template, with a format method that took a string and returned that string with a !. Is there anything I could put in the template that would be akin to format( <content></content> )? Obviously my format method would need to be a little more complicated since <content></content> is not a string, but that’s not a particularly significant problem so long as I know its type (ElementCollection? NodeList?).

Obviously, there is a workaround by just shoving everything in attributes and leaving the content empty, but I find that ugly (particularly since one cannot apparently define tags that require no close).

By : KRyan


Answers

Valid for Angular 2.0.0-alpha.45

If you are interested in child elements, that are directives or variable bindings, then this will work:

import {Component, Query QueryList} from 'angular2/angular2';

@Component({
    selector: 'c-item',
    template: '<li><ng-content></ng-content></li>'
})
export class CItem {
}


@Component({
    selector: 'c-container',
    template: '<div><ul><ng-content></ng-content></ul><strong>{{children.length}} items found.</strong></div>',
    directives: [CItem]
})
export class CContainer {
    private children:QueryList<CItem>;

    constructor(@Query(CItem) children:QueryList<CItem>) {
            this.children = children;
    }

    afterContentInit() {
            // now this.children variable is initialized properly
    }
}
By : m-szalik


Valid for Angular 2.0.0-alpha.45

You can consider a directive that allows you to access a HTMLElement and its children as well. Consider an example:

import {Directive, CORE_DIRECTIVES, ElementRef, HTMLElement} from 'angular2/angular2';


@Directive({
    selector: '[my-border]',
    inputs: [
    'definition : my-border' // attribute my-border to var definition
    ]
})
export class MyBorder {
    private definition:string;
    private elementRef : ElementRef;

    constructor(elementRef : ElementRef) {
        this.elementRef = elementRef;
    }

    afterContentInit() {
        // now this.children variable is initialized properly
        let htmlEl:HTMLElement = this.elementRef.nativeElement;
        htmlEl.setAttribute('style', 'border:' + this.definition);
    }

Then you can use it as follows:

<span my-border="dashed #00b3ee thin;">This has directive my-border</span>

The htmlEl in afterContentInit refers to span DOM element. As a result you get:

<span my-border="dashed #00b3ee thin;" style="border:dashed #00b3ee thin;">This has directive my-border</span>
By : m-szalik


This video can help you solving your question :)
By: admin