import { Directive, HostBinding, AfterViewChecked, ElementRef, Optional, Input } from '@angular/core'; import { FDropdownDirective } from './f-dropdown.directive'; @Directive({ selector: '[fDropdownMenu]' }) export class FDropdownMenuDirective implements AfterViewChecked { private _docRect = { width: 0, height: 0 }; @HostBinding('class.dropdown-menu') showDropdownMenu = true; // 内部使用,在不变更依赖的情况下,触发改变 @Input() dpIsOpen=false; constructor( private elementRef: ElementRef, private dropdown: FDropdownDirective ) { var me = this; this.dropdown.getOpenState().subscribe((state: boolean) => { me.dpIsOpen = me.dropdown.isOpen; me.openStateChange() }); } ngAfterViewChecked() { } private getRealPlacement(pment) { var result = 'bottom-right'; switch (pment) { case 'top': result = 'top-right'; break; case 'left': result = 'left-bottom'; break; case 'right': result = 'right-bottom'; break; case 'bottom': result = 'bottom-right'; break; default: result = pment; } return result; } private openStateChange() { if (this.dpIsOpen) { if (this.elementRef.nativeElement.className.indexOf('show') < 0) { this.elementRef.nativeElement.className += ' show'; if (this.dropdown.needToCalculate()) { this._docRect = this.dropdown.getRectifyReferenceEl(); } setTimeout(()=>{ this.changeDirection(); },0); } } else { if (this.elementRef.nativeElement.className.indexOf('show') > -1) { this.elementRef.nativeElement.className = this.elementRef.nativeElement.className.replace(' show', ' '); } } } private changeDirection(){ if (this.dropdown.needToCalculate()) { const rect = this.elementRef.nativeElement.getBoundingClientRect(); let placement = this.dropdown.placement; let newplacement = this.getRealPlacement(placement); placement = newplacement; // if (newplacement.indexOf('right') > -1 && rect.right > this._docRect.width ) { placement = placement.replace('right', 'left'); } if ( newplacement.indexOf('left') > -1 && rect.left - rect.width < 0 ) { placement = placement.replace('left', 'right'); } if ( newplacement.indexOf('bottom') > -1 && rect.bottom > this._docRect.height ) { placement = placement.replace('down', 'up'); } if ( newplacement.indexOf('up') > -1 && rect.bottom - rect.height < 0 ) { placement = placement.replace('up', 'bottom'); } if (newplacement !== this.dropdown.placement) { this.dropdown.placement = newplacement; } if (placement !== newplacement) { this.dropdown.placement = placement; } this.dropdown.resetCalculate(false); } } }