通过子菜单增强了下拉菜单

时间:2019-09-12 18:07:02

标签: ngx-bootstrap

我正在带有子菜单的导航栏中实现该下拉菜单,希望单击时打开菜单,而不是悬停鼠标。

我正在Angular 5中使用2.05版。我只是认为这对其他人会有所帮助。

所需的指令如下:

import {
  ChangeDetectorRef,
  Directive,
  ElementRef,
  HostBinding,
  HostListener,
  OnDestroy,
  Renderer2
} from '@angular/core';

import { Subscription } from 'rxjs';
import { BsDropdownDirective, BsDropdownState } from 'ngx-bootstrap';
//import { BsDropdownState } from './bs-dropdown.state';
//import { BsDropdownDirective } from './bs-dropdown.directive';

@Directive({
  selector: '[bsDropdownToggle2],[dropdownToggle2]',
  exportAs: 'bs-dropdown-toggle-2',
  host: {
    '[attr.aria-haspopup]': 'true'
  }
})
export class BsDropdownToggle2Directive implements OnDestroy {
  @HostBinding('attr.disabled') isDisabled: boolean = null;
  @HostBinding('attr.aria-expanded') isOpen: boolean;

  private _subscriptions: Subscription[] = [];
  private _documentClickListener: Function;
  private _escKeyUpListener: Function;

  constructor(
    private _changeDetectorRef: ChangeDetectorRef,
    private _dropdown: BsDropdownDirective,
    private _element: ElementRef,
    private _renderer: Renderer2,
    private _state: BsDropdownState
  ) {
    // sync is open value with state
    this._subscriptions.push(
      this._state.isOpenChange.subscribe(
        (value: boolean) => {
          this.isOpen = value;

          if (value) {
            this._documentClickListener = this._renderer.listen('document', 'click', (event: any) => {
              if (this._state.autoClose && event.button !== 2 &&
                !this._element.nativeElement.contains(event.target) &&
                !(event.target.attributes['aria-parentmenu'] && event.target.attributes['aria-parentmenu'].value === this._element.nativeElement.id)
              ) {
                this._state.toggleClick.emit(false);
                this._changeDetectorRef.detectChanges();
              }
            });

            this._escKeyUpListener = this._renderer.listen(this._element.nativeElement, 'keyup.esc', () => {
              if (this._state.autoClose) {
                this._state.toggleClick.emit(false);
                this._changeDetectorRef.detectChanges();
              }
            });
          } else {
            this._documentClickListener();
            this._escKeyUpListener();
          }
        }
      )
    );

    // populate disabled state
    this._subscriptions.push(
      this._state.isDisabledChange.subscribe(
        (value: boolean) => (this.isDisabled = value || null)
      )
    );
  }

  @HostListener('click', [])
  onClick(): void {
    if (this.isDisabled) {
      return;
    }
    this._state.toggleClick.emit(true);
  }

  ngOnDestroy(): void {
    if (this._documentClickListener) {
      this._documentClickListener();
    }

    if (this._escKeyUpListener) {
      this._escKeyUpListener();
    }

    for (const sub of this._subscriptions) {
      sub.unsubscribe();
    }
  }
}

通过将容器设置为主体,我可以将子菜单置于右侧。技巧是将属性“ aria-parentmenu”添加到切换元素,然后检查其是否与正在监听文档单击的元素相关。

<ul class="nav navbar-nav">
    <li dropdown
        container="body">
      <a href
         id="main-menu"
         dropdownToggle2
         (click)="false"
         aria-controls="main-menu-dropdown">Main</a>
      <ul id="main-menu-dropdown"
          *dropdownMenu
          class="dropdown-menu"
          role="menu"
          aria-labelledby="main-menu">
        <li dropdown
            placement="right"
            container="body">
          <a href
             id="sub-menu-1"
             dropdownToggle2
             (click)="false"
             aria-parentmenu="main-menu"
             aria-controls="sub-menu-1-dropdown">Sub 1</a>
          <ul id="sub-menu-1-dropdown"
              *dropdownMenu
              class="dropdown-menu"
              role="menu"
              aria-labelledby="sub-menu-1">
            <li>
              <a class="nav-link">Item 1
              </a>
            </li>
            <li>
              <a class="nav-link">Item 2</a>
            </li>
          </ul>
        </li>
        <li dropdown
            placement="right"
            container="body">
          <a href
             id="sub-menu-2"
             dropdownToggle2
             (click)="false"
             aria-parentmenu="main-menu"
             aria-controls="sub-menu-2-dropdown">Sub 2</a>
          <ul id="sub-menu-2-dropdown"
              *dropdownMenu
              class="dropdown-menu"
              role="menu"
              aria-labelledby="sub-menu-2">
            <li>
              <a class="nav-link">Item 3</a>
            </li>
          </ul>
        </li>
      </ul>
    </li>
</ul>

0 个答案:

没有答案