Innerbloom
@Innerbloom

Не получается сделать закрытие Sidebar в не его поля (clickOutside)?

Сделал слушатель который будет прослушивать клики в не его радиуса и должен закрывать сайбар но почему то он его либо не закрывает либо просто не открыват (если не открывает, мне кажется происходит дабл клик)

sidebar.component.ts дочерний компонент
export class SidebarComponent implements OnInit {

  constructor(private elementRef: ElementRef) { }

  @Input() sideNavStatus: boolean = false;
  @Output() public clickOutside = new EventEmitter<MouseEvent>();

     @HostListener('document: click', ['$event', '$event.target'])
     public onClick(event: MouseEvent, targetElement: HTMLElement) : void {
       if(!targetElement) {
         return;
       }
       const clickedInside = this.elementRef.nativeElement.contains(targetElement);
       if(!clickedInside) {
         this.clickOutside.emit(event);
       }
     }
     ngOnInit(): void { }
}


sidebar.component.html
<div class="side-nav-content">
    <ul class="nav-list" [ngClass]="{'nav-list-open': sideNavStatus}">
        <li class="nav-list-item" *ngFor="let item of list">
            <i class="{{item.icon}}"></i>
            <span>
                <a class="sidenav-nav-link" [routerLink]="item.routerLink">{{item.name}}</a>
            </span>
    </ul>
</div>


mainpage.component.ts родитель
export class MainpageComponent implements OnInit {

 sideNavStatus: boolean = false;

  constructor() { }

  ngOnInit(): void {
  }

  closeSidebar() {
      this.sideNavStatus = false
  }

}


mainpage.component.html
<div class="container-fluid g-0 sidebar-container">
    <main>

    <app-header
            (sideNavToggled)="sideNavStatus = $event;">
    </app-header>

        <app-sidebar [sideNavStatus]="sideNavStatus"
                     (clickOutside)="closeSidebar()"
                     [ngClass]="{'app-side-nav-open': sideNavStatus}">
        </app-sidebar>


        <div class="display-area p-3" [ngClass]="{'display-area-shrink': sideNavStatus}">

            <div class="container">
                <router-outlet></router-outlet>
            </div>
        </div>
    <app-footer></app-footer>
    </main>
</div>


if(!clickedInside) {
console.log('click')
this.clickOutside.emit(event);
} - тут и в консоль пробовал выводить , действительно при клике в другой области срабатывает клик, и выводил в консоль clickedInside - показывает false
Буду очень благодарен за помощь.
  • Вопрос задан
  • 77 просмотров
Решения вопроса 1
Xuxicheta
@Xuxicheta Куратор тега Angular
инженер
Попробуйте лучше так, вместо HostListener
ngOnInit() {
    fromEvent(document, 'click')
      .pipe(debounceTime(300))
      .subscribe((event) => {
           const targetElement = event.target;
           if(!targetElement) {
             return;
        }
       const clickedInside = this.elementRef.nativeElement.contains(targetElement);
       if(!clickedInside) {
         this.clickOutside.emit(event);
       }
    });
  }


Зачастую все глюки в подобных делах начинаются, когда слушатели вешаются в момент, когда компонент еще даже не нарисовался и клик не закончился.
И лучше это все таки директивой, а не в компоненте.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы