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