如何解决如何在Angular 8的primeng选项卡视图中为左右导航添加箭头?
我尝试使用 primeng,因为我的应用程序已经在 Angular 8 中安装了这个库。
除了 Angular Material 之外,是否还有其他库支持此功能?
我在这里创建了我的示例。
https://stackblitz.com/edit/primeng-tabview-ngif-hluezs
角材料示例。
https://stackblitz.com/edit/angular-selecting-mattab-bihcd1
解决方法
您可以创建自己的指令来实现此目的...
在您的 styles.css 文件中包含以下 css
.nav-wrapper {
position: relative;
overflow: hidden;
padding: 0;
}
.nav-wrapper > ul {
display: flex;
}
.nav-wrapper--scrollable {
padding: 0 32px;
}
.nav-arrow {
position: absolute;
display: none;
top: 0;
bottom: 0;
z-index: 1;
border: 1px solid #2399e5;
background: #2399e5;
font: 14px/1 FontAwesome;
color: #fff;
cursor: pointer;
}
.nav-wrapper--scrollable .nav-arrow {
display: block;
}
.nav-arrow:hover {
border: 1px solid #1f89ce;
background: #1f89ce;
}
.nav-arrow:before {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
.nav-arrow--left {
left: 0;
}
.nav-arrow--left:before {
content: "\f053";
}
.nav-arrow--right {
right: 0;
}
.nav-arrow--right:before {
content: "\f054";
}
.nav-arrow--disabled,.nav-arrow--disabled:hover {
background: #ccc;
border: #ddd;
cursor: default;
}
创建指令
import {
ContentChildren,Directive,ElementRef,Input,NgZone,QueryList
} from "@angular/core";
import { TabPanel } from "primeng/tabview";
import { fromEvent,interval,Subject } from "rxjs";
import { delay,mergeMap,take,takeUntil } from "rxjs/operators";
@Directive({
selector: "[appTabScroller]"
})
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;
}
现在一切都设置好了,在你的 html 中
<p-tabView appTabScroller>
<p-tabPanel [header]="item.content" *ngFor="let item of items; let i = index" [selected]="i == 0">
</p-tabPanel>
</p-tabView>
来源:https://embed.plnkr.co/BX6UTrG7XTBXS2TNChAs/
,我分叉了您的示例,并在顶部添加了一些示例按钮,可以转到上一个/下一个选项卡。当然,您可以通过几种不同的方式来做到这一点。
https://stackblitz.com/edit/primeng-tabview-ngif-2e96sb?file=src/app/app.component.html
让我知道 CSS 是否是更多问题,因为这主要是为了展示功能。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。