10
votes

How to target a specific element inside a component in Angular Directive.
I have a component with selector "highlighter". This component has content project using ng-content.
There is a directive with selector "highlighter input".
I believe this directive should get applied to any input only inside the highlighter component only but it gets applied to all the inputs in the application - whats wrong?

Plunker: https://plnkr.co/edit/4zd31C?p=preview

@Component({
  selector: 'highlighter',
  template: `
    This should be highlighted: 
    <ng-content></ng-content>
  `
})
export class HighlighterComponent {
}

@Directive({
  selector: 'highlighter input'
})
export class HighlightDirective {
    constructor(el: ElementRef) {
       el.nativeElement.style.backgroundColor = 'yellow';
    }
}
3

3 Answers

7
votes

Selectors in Angular don't support combinators:

- descendant selector (space)
- child selector (>)
- adjacent sibling selector (+)
- general sibling selector (~)

So the last distinct selector in the string wins, which is input in your case. That's why it's applied to all inputs.

Another thing is that projected content is not considered to be located inside a component to which is projected. So even if Angular supported combinator selectors, the selector highlighter input still shouldn't work.

The simplest solution would be to add a class to the input like this:

<input class="highlighter">

and target this class in the selector:

@Component({
  selector: 'input.highlighter'
1
votes

One clue that I found in the Angular doc is that:

Angular only allows directives to trigger on CSS selectors that do not cross element boundaries.

0
votes

Directives will be applied to all selectors within the module it is declared.