'How to affect the directive children using @HostBinding?

I'm implementing a bootsrap's single button dropdown (docs).

In order to make it to be "open", it must add a show class to main <div> and to the <ul>.

This is closed:

<div class="btn-group">
  <button
      type="button"
      class="btn btn-primary dropdown-toggle">
      Manage (Using Directive) <span class="caret"></span>
    </button>
  <ul class="dropdown-menu">
    <li><a style="cursor: pointer;">Edit </a></li>
    <li><a style="cursor: pointer;">Delete </a></li>
  </ul>
</div>

This is open:

<div class="btn-group show">
  <button
      type="button"
      class="btn btn-primary dropdown-toggle">
      Manage (Using Directive) <span class="caret"></span>
    </button>
  <ul class="dropdown-menu show">
    <li><a style="cursor: pointer;">Edit </a></li>
    <li><a style="cursor: pointer;">Delete </a></li>
  </ul>
</div>

I'm trying to make it work as a directive with:

<div class="btn-group" appDropdown>
  <button
      type="button"
      class="btn btn-primary dropdown-toggle">
      Manage (Using Directive) <span class="caret"></span>
    </button>
  <ul class="dropdown-menu">
    <li><a style="cursor: pointer;">Edit </a></li>
    <li><a style="cursor: pointer;">Delete </a></li>
  </ul>
</div>

And the dropdown.directive.ts:

import { Directive, HostListener, HostBinding } from '@angular/core';

@Directive({
  selector: '[appDropdown]'
})
export class DropdownDirective {
  @HostBinding('class.show') isOpen = false;

  @HostListener('click') toggleOpen() {
    this.isOpen = !this.isOpen;
  }
}

This way I'm only able to add the show class to the <div> without adding it to the <ul>, Is there a way to affect the directive children?

Here is a StackBlitz

This is a related question, but it does not mention any @HostBinding



Solution 1:[1]

I came across this post when I was looking for the answer to the same question. I solved the issue myself using ElementRef. I'm fairly new to Angular but coming from a React background I thought if the 'Ref' in element ref is similar to Refs in React then it should have HTML attributes & properties, specifically querySelector.

So if anyone else is stumped on this, this can serve as a solution.

import { Directive, HostListener, ElementRef } from '@angular/core';

@Directive({
  selector: '[appDropdown]',
})
export class DropdownDirective {
  constructor(private dropdownRef: ElementRef<HTMLElement>) {}

  @HostListener('click') toggleOpen = () => {
    this.dropdownRef.nativeElement
      .querySelector('div')
      .classList.toggle('hidden');
  };
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jose Munoz