Dzisiaj krótki art o świetnej funkcjonalności, która pojawiła się w nowej wersji Angulara 6.1.0-beta.1. Wielokrotnie irytowało mnie zachowanie scrolla w aplikacjach angularowych i w pewnych przypadkach niestety nie dało się obejść bez serwisu zarządzającego scrollem. Panowie z Angulara wpadli w końcu na genialny pomysł, aby scroll zachowywał się jak na scrolla przystało 😉
Problem scrolla
Wyobraź sobie sytuację, że chcesz przejść do widoku i od razu ustawić wysokość strony na odpowiedniej kotwicy. Przykład:
Template widoku A:
1 |
<a routerLink="some-view" fragment="someAnchor" style="margin-top: 300px;display: block">Go to view B</a> |
Template widoku B:
1 |
<div id="someAnchor" style="margin-top: 600px">B view</div> |
Na linku użyłem właściwość fragment, która doklei kotwicę do URLa po przejściu do widoku B:
1 |
http://localhost:4200/b-view#someAnchor |
Z racji, że div w widoku B ma margines górny ustawiony na 600px, to spodziewam się, że po przejściu na widok B, wartość scroll.Y ustawi się na 600px. Oczekuję również, że jak kliknę w przeglądarce strzałkę wstecz, to scroll wróci na pozycję Y o wartości 300px, no bo przeszedłem z widoku właśnie na takiej wysokości. Niestety tak się nie dzieje 🙁 Standardowo przeglądarka obsługuje takie zachowanie, ale w przypadku aplikacji SPA nie jest to już domyślna funkcjonalność.
AnchorScrolling & ScrollPositionRestoration to the rescue!
Od wresji 6.1.0 z pomocą przychodzą nam dwie nowe opcje dla konfiguracji Routera:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@NgModule({ declarations: [ AppComponent, SomeViewComponent ], imports: [ BrowserModule, RouterModule.forRoot([{ path: 'some-view', component: SomeViewComponent}], { anchorScrolling: 'enabled', scrollPositionRestoration: 'enabled'}) ], providers: [], bootstrap: [AppComponent] }) |
Konfigurację Routera możemy zmienić przekazując obiekt konfiguracyjny jako drugi parametr w metodzie forRoot.
Spójrzmy co mamy nowego do dyspozycjI:
- anchorScrolling: 'disabled’ | 'enabled’ (domyślnie disabled)
- scrollPositionRestoration: 'disabled’ | 'top’ | 'enabled’ (domyślnie disabled)
W obu właściwościach disabled jest domyślny, ale to się zmieni w przyszłości na enabled. Wartość ’top’ oznacza, aby po powrocie scrollować zawsze do [0, 0] czyli do góry strony.
ScrollPositionRestoration: 'enabled’ odpowiada za to, aby po powrocie do poprzedniej strony, scroll był na takiej pozycji, z której przyszliśmy.
Natomiast zmiana na ’enabled’ w anchorScrolling zapewni nam, że po przejściu do URL z kotwicą, przeglądarka przeskoczy scrollem do odpowiedniej wysokości.
Sprawdziłem obie konfiguracje i działają naprawdę świetnie, już nie mogę się doczekać migracji do 6.1.0 :))
ViewportScroller
ViewportScroller to z kolei nowy serwis, który pozwoli nam korzystać z wartości scrolla. Na githubie pojawił się przykład:
1 |
import { ViewportScroller } from '@angular/common'; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class ListComponent { list: any[]; constructor(router: Router, viewportScroller: ViewportScroller, fetcher: ListFetcher) { const scrollEvents = router.events.filter(e => e instanceof Scroll); listFetcher.fetch().pipe(withLatestFrom(scrollEvents)).subscribe(([list, e]) => { this.list = list; if (e.position) { viewportScroller.scrollToPosition(e.position); } else { viewportScroller.scrollToPosition([0, 0]); } }); } } |
COMMIT LINK Z PRZYKŁADAMI: https://github.com/angular/angular/commit/49c5234
Także możemy teraz korzystać ze scrolla dla specyficznego komponentu oraz do ekipy RouterEvents dołączył nowy gracz: Scroll.
Scroll jest ostatnim eventem, wywołanym po NavigationEnd. Zachęcam do przejrzenia linka z commitem i zapoznania się z przykładami i kodem źródłowym. ViewportScroller po prostu opakowuje window.scrollTo w wygodne API. Natomiast nowy Scroll Event tak wygląda:
1 2 3 4 5 6 7 8 9 10 11 12 |
* Represents a scrolling event. */ export declare class Scroll { readonly routerEvent: NavigationEnd; readonly position: [number, number] | null; readonly anchor: string | null; constructor( routerEvent: NavigationEnd, position: [number, number] | null, anchor: string | null); toString(): string; } |
Jak widzisz, daje nam dostęp do takich właściwości jak pozycja scrolla i kotwicy.
Jeśli nie są znane Ci RouterEvents, to zachęcam do przeczytania artykułu:
http://angular.love/2017/06/17/angular-router-events-i-spinner/
Wkrótce Angular 6.1.0 wejdzie na rynek, na razie jest na etapie RC.0, ale warto pamiętać o tym nowym bajerze z ustawieniem scrolla!
Dodaj komentarz