plone1
plone1

Reputation: 676

Angular2: Component composed of multiples directives

Version: "angular2": "2.0.0-beta.6"

We assume that we have two @Directive

How can I create a @Component that implements this two @Directive?

@Component({
    selector: 'test',
    template: '{{text}}',
    //Looking from something like that..
    //using: [HighLightDirective, UnderlineDirective]
})
export class TestComponent {
    public text:string;
    //maybe? constructor(hightlight,underline)
}

PS: I know that I can do this by changing the Component template like below. Does something more elegant exists ?

'<div highlight underline>{{text}}</div>'

Upvotes: 1

Views: 932

Answers (2)

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

Reputation: 658087

You could use the same selector for the directives and the component.

@Directive({selector: 'test'})
class HighlightDirective {
}

@Directive({selector: 'test'})
class UnderlineDirective {}

@Component({
    selector: 'test',
    directives: []
    template: '{{text}}',
    //Looking from something like that..
    //using: [HighLightDirective, UnderlineDirective]
})
export class TestComponent {
  constructor(@Self()hs:HighlightDirective, @Self()hs:UnderlineDirective) {}
}

@Component({
  selector: 'my-app',
  directives: [TestComponent,HighlightDirective, UnderlineDirective]
  template: `
  <h2>Hello</h2>
  <test></test>

`
})
export class App {

}

Plunker example

If you want to use the directives independendly of the component you can add multiple selectors like

@Directive({selector: 'test,highlight'})
class HighlightDirective {
}

The constructor throws when HighlightDirective and UnderlineDirective are not applied

  constructor(@Self()hs:HighlightDirective, @Self()hs:UnderlineDirective) {}

You can also add the directives to PLATFORM_DIRECTIVES

bootstrap(MyComponent, [provide(PLATFORM_DIRECTIVES, {useValue: [HighlightDirective, UnderlineDirective], multi:true})]);

to get them applied everywhere where the selector matches, without adding them to directives: [HighlightDirective, UnderlineDirective] of every component where you want to use them.

Upvotes: 2

drew moore
drew moore

Reputation: 32680

//Looking from something like that..
//using: [HighLightDirective, UnderlineDirective]

What you're looking for is the directives property:

@Component({
    selector: 'test',
    template: '<div highlight underline>{{text}}</div>',
    directives: [HighLightDirective, UnderlineDirective] // don't forget to import them!
})
export class TestComponent {
    @Input() // don't forget this!
    public text:string;
    constructor() {} //no need to do anything here
}

I misunderstood your question initially and thought you were just confused about the metadata key to use - if you are, then see above.

In terms of "automatically" applying these directives to the component template, IMHO there's nothing inelegant about applying them them in the template as you have, and anything "more elegant" would be proportionally less clear. In any case, no, there is no alternative, and doing what you're doing here is perfectly idiomatic.

This is all assuming your actual use case is more complex than this question, otherwise (since you're not adding anything new in your template) Component is the wrong tool here and you should simply apply the two directives directly. If you're really dead-set against doing that and your use case is actually this simple, I suppose

@Component({
    selector: 'test',
    template: '<div highlight underline><ng-content></ng-content></div>',
    directives: [HighLightDirective, UnderlineDirective] 
})
export class TestComponent { }

which you could then use as: <test>stuff</test> rather than <test [text]="someVar"></test> would be more elegant... but it still doesn't make much sense to me.

Upvotes: 1

Related Questions