Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 4 Directive selector to target an element inside a component only

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';
    }
}
like image 744
Suresh Nagar Avatar asked Jan 14 '18 22:01

Suresh Nagar


People also ask

How can I select an element in a component template?

Add a template reference variable to the component HTML element. Import @ViewChild decorator from @angular/core in component ts file. Use ViewChild decorator to access template reference variable inside the component.

Can we access DOM element inside Angular component constructor method?

You can get a handle to the DOM element via ElementRef by injecting it into your component's constructor: constructor(private myElement: ElementRef) { ... }

What is @directive in Angular?

What is meant by directives in Angular? Directives are classes that add new behavior or modify the existing behavior to the elements in the template. Basically directives are used to manipulate the DOM, for example adding/removing the element from DOM or changing the appearance of the DOM elements.

What is Contentprojection?

Content projection is a pattern in which you insert, or project, the content you want to use inside another component. For example, you could have a Card component that accepts content provided by another component.


1 Answers

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'
like image 54
Max Koretskyi Avatar answered Oct 06 '22 00:10

Max Koretskyi