W Angularze mam routing dla 3 opcjonalnych parametrów, ale ponieważ opcjonalne parametry są dość brzydkie w angularowym URL, to stworzyłem 4 ścieżki routingu z wymaganymi parametrami kierującymi do tego samego komponentu.
W głównym pliku routingu mam:
routes: Routes = [
{path: 'elo', loadChildren: '/modules/elo.module#EloModule'}
];
A w komponencie wspomniane ścieżki:
routes: Routes = [
{path: ':p1/:p2:/p3', component: EloComponent},
{path: ':p1/:p2', component: EloComponent},
{path: ':p1', component: EloComponent},
{path: '', component: EloComponent}
];
W komponencie natomiast mam dynamiczne dropdowny i datepicker.
Przy wejściu na stronę leci żądanie i wynik wrzucany jest w pierwszy dropdown P1
. Jak user coś tam wybierze, to leci żądanie o zawartość P2
, a jak już to mamy, to datepicker staje się dostępny i user może wybrać P3
. Wtedy odpala się dalsza część kodu.
To wszystko działo się tylko w kodzie, bez zmiany URL, więc każde odświeżenie strony czyściło wybór usera, co jest dalekie od dobrego UX. I tu pojawiły się kłopoty.
P1
było dość łatwo zrobić przez combineLatest(this.route.paramMap, this.p1Service.getData()).subscribe(...)
. Czyli subskrybcja na Observable routera i zmianę URL oraz pobranie zawartości P1
. Jak mamy dane, pobieram p1
z URL i ustawiam w modelu P1
by ten był odpowiednio wybrany. Tu luzik. Jak user zmieni P1
to jedyne co robię, to this.router.navigate([/elo', this.p1])
, angular przechodzi na http://app/elo/p1valueA
, powyższy combineLatest odpala funkcję z subscribe i wszystko gra.
Sęk w tym, że P2
zależy od wybranej pozycji P1
, więc nie można zdefiniować observabla wcześniej. Wymyśliłem dwa podejścia, oba wyglądają bardzo niechlujnie. Jedno to w powyższym subscribe tworzyć nowy request o dane dla P2
i zagnieżdżony observable/subscribe obsługujący P2
.
Drugi z udziałem BehaviorSubject, gdzie dane są wrzucane w .next(...)
dzięki czemu jest ciut czyściej, bo nie ma zagnieżdżonych observable/subscribe, a jeden pod drugim i combineLatest(this.route.paramMap, this.p1Data$).subscribe(...)
.
Obie wersje wydają mi się brzydkie, przekombinowane, nieczytelne nawet dla mnie, a co dopiero dla kogoś, kto miałby dołączyć do projektu. Poza tym generują dodatkowe problemy, bo będąc zasubskrybowanym na zmianę URL, zmiana p2
albo p3
odpala zmianę dla p1
co tworzy pewne błędne koło i pobiera niepotrzebnie dane, które już mamy.
Uff, brzmi może skomplikowanie, ale generalnie brzmi, jakby temat mógł dotyczyć wielu aplikacji, a nie umiałem nic wygooglać.
W skrócie:
- Wchodząc na http://app/elo chcę:
- pobrać dane do
P1
- Wchodząc na http://app/elo/p1valA chcę:
- pobrać dane do
P1
i ustawićp1valA
jako wybraną opcję - pobrać dane do
P2
- Wchodząc na http://app/elo/p1valA/p2valX chcę:
- pobrać dane do
P1
i ustawićp1valA
jako wybraną opcję - pobrać dane do
P2
i ustawićp2valX
jako wybraną opcję (co włączy date pickera, bo oba P zostały wybrane)
- Wchodząc na http://app/elo/p1valA/p2valX/p3valG chcę:
- pobrać dane do
P1
i ustawićp1valA
jako wybraną opcję - pobrać dane do
P2
i ustawićp2valX
jako wybraną opcję (co włączy date pickera, bo oba P zostały wybrane) - ustawić
P3
nap3valG
- Zmieniając P1 ręcznie chcę zmienić url na http://app/elo/p1NewVal ale nie pobierać już danych do
P1
- już je mamy - Zmieniając P2 ręcznie chcę zmienić url na http://app/elo/p1valA/p2NewVal ale nie pobierać już danych do
P1
ANIP2
- już je mamy - Zmieniając P3 ręcznie chcę zmienić url na http://app/elo/p1valA/p2valX/p3NewVal ale nie pobierać już danych do
P1
ANIP2
- już je mamy
Czy po takim opisie problem jest jasny i możliwy do prostego oprogramowania? Mam wrażenie, że za długo w tym siedziałem i mam już widzenie lunetkowe i nie umiem spojrzeć świeżym okiem i marnuję czas.