import { Component, OnInit, HostBinding, Input, ContentChildren, AfterContentInit, QueryList, ComponentFactoryResolver, ViewContainerRef, Injector, ApplicationRef, Renderer2, ElementRef, ViewChild, AfterViewInit } from '@angular/core'; import { SplitterPaneComponent } from './splitter-pane.component'; import { SplitterBarComponent } from './splitter-bar.component'; @Component({ selector: 'farris-splitter', template: ` `, styles: [] }) export class SplitterComponent implements OnInit, AfterContentInit, AfterViewInit { @HostBinding('class.f-component-splitter') splitterCls = true; // @HostBinding('class.d-flex') flexCls = true; @Input() orientation = "horizontal"; hostEl: HTMLElement; @ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef; @ContentChildren(SplitterPaneComponent) pane: QueryList; barComponentRefArray: any[] = []; constructor( private componentFactoryResolver: ComponentFactoryResolver, private injector: Injector, private renderer: Renderer2, private elementRef: ElementRef ) { } ngOnInit() { } ngAfterContentInit() { } ngAfterViewInit() { //使用的是ngResizable,没有使用Bar,此处方法可不执行 this.hostEl = this.elementRef.nativeElement; // this.initPane(); } initPane() { if (this.pane && this.pane['_results'] && this.pane['_results'].length) { let hostWidth = this.hostEl.offsetWidth; const length = this.pane['_results'].length; const restPane = this.pane['_results'].filter(item => { return !item._size; }); const restLength = restPane.length; this.pane['_results'].forEach((item, index) => { item.order = index * 2; if (!!item._size) { hostWidth = hostWidth - this.getElementSize(hostWidth, item._size); } }) restPane.forEach(item => { item.size = hostWidth / restLength; }) if (length > 1) { this.createBar(length - 1); } this.listenPaneSizeChange(); } } listenPaneSizeChange() { const hostWidth = this.hostEl.offsetWidth; this.pane['_results'].forEach((item, index) => { item.sizeChange.subscribe(size => { const nextIndex = index + 1; const diff = item.el.offsetWidth - size; if (this.pane['_results'][nextIndex]) { const nextPaneMin = this.getElementSize(hostWidth, this.pane['_results'][nextIndex].min); if (this.barComponentRefArray[nextIndex]) { // 拖拽向左的最大宽度 if (nextPaneMin >= item.el.offsetWidth || nextPaneMin <= 0) { this.barComponentRefArray[nextIndex].instance.leftMovedMax = this.pane['_results'][nextIndex].el.offsetWidth + diff; } else { this.barComponentRefArray[nextIndex].instance.leftMovedMax = this.pane['_results'][nextIndex].el.offsetWidth + diff - nextPaneMin; } } } }) }) } // 获取目标元素的size getElementSize(hostWidth: number, size: any): number { let targetSize: number; if (!size) { targetSize = 0; return targetSize; } if (size.indexOf('px') !== -1 || typeof size === 'number') { targetSize = parseInt(size); } else if (size.indexOf('%') !== -1) { targetSize = hostWidth * parseInt(size) / 100; } return targetSize; } createBar(len: number) { let size: any; const hostWidth = this.hostEl.offsetWidth; for (let i = 0; i < len; i++) { const factory = this.componentFactoryResolver.resolveComponentFactory(SplitterBarComponent); const componentRef = this.container.createComponent(factory); const prevPane = this.pane['_results'][i]; const prevPaneOriginWidth = prevPane.el.offsetWidth; const nextPane = this.pane['_results'][i + 1]; const nextPaneOriginWidth = nextPane.el.offsetWidth; const prePaneMax = this.getElementSize(hostWidth, this.pane['_results'][i].max); const prePaneMin = this.getElementSize(hostWidth, this.pane['_results'][i].min); // 拖拽向右的最大宽度 if (prePaneMax <= prevPaneOriginWidth && prePaneMax > 0) { componentRef.instance.rightMovedMax = 0; } else if (prePaneMax >= prevPaneOriginWidth + nextPaneOriginWidth || prePaneMax === 0) { componentRef.instance.rightMovedMax = nextPaneOriginWidth; } else { componentRef.instance.rightMovedMax = prePaneMax - prevPaneOriginWidth; } // 拖拽向左的最大宽度 if (prePaneMin >= prevPaneOriginWidth || prePaneMin <= 0) { componentRef.instance.leftMovedMax = prevPaneOriginWidth; } else { componentRef.instance.leftMovedMax = prevPaneOriginWidth - prePaneMin; } // 横向拖拽还是纵向拖拽 if (this.orientation === 'horizontal') { componentRef.instance.lockAxis = 'y'; } else if (this.orientation === 'vertical') { componentRef.instance.lockAxis = 'x'; } componentRef.instance.order = 2 * i + 1; // 拖拽变化 componentRef.instance.endOffset.subscribe(data => { prevPane.size = prevPane.el.offsetWidth + data.x; nextPane.size = nextPane.el.offsetWidth - data.x; // console.log(prevPanelOriginWidth + data.x, nextPanelOriginWidth - data.x) }) this.barComponentRefArray.push(componentRef); componentRef.changeDetectorRef.detectChanges(); } } }