我的Tabs运行得很好。如果您点击加号(+),您就可以添加标签,也许在添加 3或4个标签后,您会看到 tabBar滚动条两端都有按钮。这是使用ExtJS完成的,效果很好!
工作代码: Example Code
基本上,在某个宽度之后,我想展示那些允许用户从左右或左右导航的滚动条。有谁知道如何做到这一点?非常感谢提前!
这是我的代码:
<p-tabView>
<p-tabPanel header="one">
<button (click)="showSecondTab()">Show Second Tab</button>
</p-tabPanel>
<p-tabPanel header="two">
</p-tabPanel>
<p-tabPanel header="three">
</p-tabPanel>
<p-tabPanel header="fourt">
</p-tabPanel>
<p-tabPanel header="five">
</p-tabPanel>
.......
.......
.......
</p-tabView>
答案 0 :(得分:1)
目前,primeng包中没有内置功能。因此,我会考虑编写一些指令来实现所有期望的行为并自行完成所有工作。
该指令将包含处理此类事件的所有内容,例如箭头上的window:scroll
,click|long click
,选项卡上的mousewhell
。对于这样的事情,我要使用rxjs流。
它还会做一些DOM操作,比如在容器中包装标签并创建箭头。
它还将通过p-tabPanel
ContentChildren.changes
组件的更改
最后,结果应该如下:
标签-scroller.directive.ts 强>
import { Directive, ElementRef, NgZone, Input, ContentChildren, QueryList } from '@angular/core';
import { TabPanel } from 'primeng/primeng';
import { interval } from 'rxjs/observable/interval';
import { of } from 'rxjs/observable/of';
import { fromEvent } from 'rxjs/observable/fromEvent';
import { Subject } from 'rxjs/Subject';
import { takeUntil } from 'rxjs/operators/takeUntil';
import { mergeMap } from 'rxjs/operators/mergeMap';
import { take } from 'rxjs/operators/take';
import { delay } from 'rxjs/operators/delay';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/observable/of';
@Directive({
selector: '[tabScroller]',
})
export class TabScrollerDirective {
@Input() arrowWidth = 30;
@Input() shiftWidth = 25;
@ContentChildren(TabPanel) tabPanels: QueryList<TabPanel>;
private _container: HTMLElement;
private _nav: HTMLElement;
private _shift = 0;
private _scrollable: boolean;
private _leftArrow: HTMLElement;
private _rightArrow: HTMLElement;
private readonly _destroyed$ = new Subject<void>();
constructor(
private elRef: ElementRef,
private zone: NgZone) { }
get rightBorder() {
return -(this._nav.scrollWidth - this._nav.offsetWidth);
}
ngAfterContentInit() {
this.tabPanels.changes
.pipe(takeUntil(this._destroyed$))
.subscribe(() => {
this.zone.onStable.asObservable()
.pipe(take(1))
.subscribe(() => this._refreshScroller());
})
}
ngAfterViewInit() {
this.zone.runOutsideAngular(() => this.init());
}
init() {
this._nav = this.elRef.nativeElement.querySelector('[role=tablist]');
this._container = wrap(this._nav, 'nav-wrapper');
this._initEvents();
this._leftArrow = this._createArrow('left');
this._rightArrow = this._createArrow('right');
this._refreshScroller();
}
scroll(shift: number) {
this._shift += shift;
const rightBorder = this.rightBorder;
if (this._shift < rightBorder) {
this._shift = rightBorder;
}
if (this._shift >= 0) {
this._shift = 0;
}
this._leftArrow.classList.toggle('nav-arrow--disabled', this._shift >= 0);
this._rightArrow.classList.toggle('nav-arrow--disabled', this._shift <= rightBorder);
this._nav.style.transform = `translateX(${this._shift}px)`;
}
ngOnDestroy() {
this._destroyed$.next();
this._destroyed$.complete();
}
private _initEvents() {
fromEvent(this._container, 'mousewheel')
.pipe(takeUntil(this._destroyed$))
.subscribe((e: any) => this._onMouseWheel(e));
// Firefox
fromEvent(this._container, 'DOMMouseScroll')
.pipe(takeUntil(this._destroyed$))
.subscribe((e: any) => this._onMouseWheel(e));
fromEvent(window, 'resize')
.pipe(takeUntil(this._destroyed$))
.subscribe(() => {
this._refreshScroller();
});
}
private _onMouseWheel(e: any) {
const delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
this.scroll(delta * 25);
}
private _createArrow(direction: string) {
const arrow = el(`nav-arrow nav-arrow--${direction}`);
this._container.insertBefore(arrow, this._nav);
arrow.style.width = this.arrowWidth + 'px';
fromEvent(arrow, 'click')
.pipe(takeUntil(this._destroyed$))
.subscribe(() => {
this.scroll(direction === 'left' ? this.shiftWidth : -this.shiftWidth);
});
const upStream$ = fromEvent(arrow, 'mouseup');
// handle long press
fromEvent(arrow, 'mousedown')
.pipe(
takeUntil(this._destroyed$),
mergeMap((event) => interval(100).pipe(delay(100), takeUntil(upStream$)))
)
.subscribe(() => {
this.scroll(direction === 'left' ? this.shiftWidth : -this.shiftWidth);
});
return arrow;
}
private _refreshScroller() {
const compareWith = (this._scrollable ? -this.arrowWidth * 2 : 0);
this._container.classList.toggle('nav-wrapper--scrollable', this.rightBorder < compareWith);
this._scrollable = this.rightBorder < compareWith;
this.scroll(0);
}
}
function wrap(elem, wrapperClass: string) {
const wrapper = el('nav-wrapper');
elem.parentNode.insertBefore(wrapper, elem);
wrapper.appendChild(elem);
return wrapper;
}
function el(className: string): HTMLElement {
const div = document.createElement('div');
div.className = className;
return div;
}
您需要做的最后一件事是在p-tabView
元素上应用此指令:
<p-tabView tabScroller>
...
</p-tabView>
<强> Plunker Example 强>
<强> Ng-run Example 强>