Router
स्वयं का उपयोग उन मुद्दों का कारण होगा जिन्हें आप लगातार ब्राउज़र अनुभव को बनाए रखने के लिए पूरी तरह से दूर नहीं कर सकते हैं। मेरी राय में सबसे अच्छा तरीका सिर्फ एक रिवाज का उपयोग करना है directive
और इसे क्लिक पर स्क्रॉल को रीसेट करने देना है। इसके बारे में अच्छी बात यह है कि यदि आप उसी पर हैं जिस पर url
आप क्लिक करते हैं, तो पृष्ठ शीर्ष पर भी वापस स्क्रॉल करेगा। यह सामान्य वेबसाइटों के अनुरूप है। मूल directive
कुछ इस तरह दिख सकता है:
import {Directive, HostListener} from '@angular/core';
@Directive({
selector: '[linkToTop]'
})
export class LinkToTopDirective {
@HostListener('click')
onClick(): void {
window.scrollTo(0, 0);
}
}
निम्नलिखित उपयोग के साथ:
<a routerLink="/" linkToTop></a>
यह अधिकांश उपयोग के मामलों के लिए पर्याप्त होगा, लेकिन मैं कुछ मुद्दों की कल्पना कर सकता हूं जो इससे उत्पन्न हो सकते हैं:
universal
के उपयोग के कारण पर काम नहीं करता हैwindow
- परिवर्तन का पता लगाने पर छोटे गति का प्रभाव, क्योंकि यह हर क्लिक से चालू होता है
- इस निर्देश को अक्षम करने का कोई तरीका नहीं है
इन मुद्दों को दूर करना वास्तव में काफी आसान है:
@Directive({
selector: '[linkToTop]'
})
export class LinkToTopDirective implements OnInit, OnDestroy {
@Input()
set linkToTop(active: string | boolean) {
this.active = typeof active === 'string' ? active.length === 0 : active;
}
private active: boolean = true;
private onClick: EventListener = (event: MouseEvent) => {
if (this.active) {
window.scrollTo(0, 0);
}
};
constructor(@Inject(PLATFORM_ID) private readonly platformId: Object,
private readonly elementRef: ElementRef,
private readonly ngZone: NgZone
) {}
ngOnDestroy(): void {
if (isPlatformBrowser(this.platformId)) {
this.elementRef.nativeElement.removeEventListener('click', this.onClick, false);
}
}
ngOnInit(): void {
if (isPlatformBrowser(this.platformId)) {
this.ngZone.runOutsideAngular(() =>
this.elementRef.nativeElement.addEventListener('click', this.onClick, false)
);
}
}
}
यह अधिकांश उपयोग-मामलों को ध्यान में रखता है, मूल एक के समान उपयोग के साथ, इसे सक्षम / अक्षम करने के लाभ के साथ:
<a routerLink="/" linkToTop></a> <!-- always active -->
<a routerLink="/" [linkToTop]="isActive"> <!-- active when `isActive` is true -->
यदि आप विज्ञापित नहीं होना चाहते हैं तो विज्ञापन न पढ़ें
एक और सुधार यह देखने के लिए किया जा सकता है कि ब्राउज़र passive
घटनाओं का समर्थन करता है या नहीं । यह कोड को थोड़ा और जटिल कर देगा, और थोड़ा अस्पष्ट है यदि आप इन सभी को अपने कस्टम निर्देश / टेम्प्लेट में लागू करना चाहते हैं। इसलिए मैंने एक छोटी सी लाइब्रेरी लिखी जिसका उपयोग आप इन समस्याओं को दूर करने के लिए कर सकते हैं। ऊपर की तरह ही कार्यक्षमता है, और अतिरिक्त passive
घटना के साथ, आप अपने निर्देश को इस में बदल सकते हैं, यदि आप ng-event-options
पुस्तकालय का उपयोग करते हैं । तर्क click.pnb
श्रोता के अंदर है:
@Directive({
selector: '[linkToTop]'
})
export class LinkToTopDirective {
@Input()
set linkToTop(active: string|boolean) {
this.active = typeof active === 'string' ? active.length === 0 : active;
}
private active: boolean = true;
@HostListener('click.pnb')
onClick(): void {
if (this.active) {
window.scrollTo(0, 0);
}
}
}
RouterModule.forRoot(appRoutes, { scrollPositionRestoration: 'enabled' })