mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 06:44:17 +00:00
feat: correctly support relative routing for FlatRoutes
This commit is contained in:
parent
4784b2ddab
commit
88004e5042
1 changed files with 52 additions and 10 deletions
|
@ -1,4 +1,5 @@
|
|||
use crate::{
|
||||
hooks::Matched,
|
||||
location::{LocationProvider, Url},
|
||||
matching::Routes,
|
||||
params::ParamsMap,
|
||||
|
@ -49,7 +50,8 @@ where
|
|||
owner: Owner,
|
||||
params: ArcRwSignal<ParamsMap>,
|
||||
path: String,
|
||||
url: ArcRwSignal<Url>
|
||||
url: ArcRwSignal<Url>,
|
||||
matched: ArcRwSignal<String>
|
||||
}
|
||||
|
||||
impl<Defs, Fal, R> Mountable<R> for FlatRoutesViewState<Defs, Fal, R>
|
||||
|
@ -98,6 +100,12 @@ where
|
|||
// we always need to match the new route
|
||||
let new_match = routes.match_route(current_url.path());
|
||||
let id = new_match.as_ref().map(|n| n.as_id());
|
||||
let matched = ArcRwSignal::new(
|
||||
new_match
|
||||
.as_ref()
|
||||
.map(|n| n.as_matched().to_owned())
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
|
||||
// create default starting points for owner, url, path, and params
|
||||
// these will be held in state so that future navigations can update or replace them
|
||||
|
@ -120,10 +128,10 @@ where
|
|||
params,
|
||||
path,
|
||||
url,
|
||||
matched,
|
||||
})),
|
||||
Some(matched) => {
|
||||
let matched_str = matched.as_matched();
|
||||
let (view, child) = matched.into_view_and_child();
|
||||
Some(new_match) => {
|
||||
let (view, child) = new_match.into_view_and_child();
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
if child.is_some() {
|
||||
|
@ -135,9 +143,11 @@ where
|
|||
let mut view = Box::pin(owner.with(|| {
|
||||
ScopedFuture::new({
|
||||
let url = url.clone();
|
||||
let matched = matched.clone();
|
||||
async move {
|
||||
provide_context(params_memo);
|
||||
provide_context(url);
|
||||
provide_context(Matched(ArcMemo::from(matched)));
|
||||
view.choose().await
|
||||
}
|
||||
})
|
||||
|
@ -151,6 +161,7 @@ where
|
|||
params,
|
||||
path,
|
||||
url,
|
||||
matched,
|
||||
})),
|
||||
None => {
|
||||
let state =
|
||||
|
@ -161,6 +172,7 @@ where
|
|||
params,
|
||||
path,
|
||||
url,
|
||||
matched,
|
||||
}));
|
||||
|
||||
Executor::spawn_local({
|
||||
|
@ -208,6 +220,10 @@ where
|
|||
// otherwise, match the new route
|
||||
let new_match = routes.match_route(url_snapshot.path());
|
||||
let new_id = new_match.as_ref().map(|n| n.as_id());
|
||||
let matched_string = new_match
|
||||
.as_ref()
|
||||
.map(|n| n.as_matched().to_owned())
|
||||
.unwrap_or_default();
|
||||
let matched_params = new_match
|
||||
.as_ref()
|
||||
.map(|n| n.to_params().into_iter().collect())
|
||||
|
@ -216,6 +232,7 @@ where
|
|||
// if it's the same route, we just update the params
|
||||
if new_id == initial_state.id {
|
||||
initial_state.params.set(matched_params);
|
||||
initial_state.matched.set(matched_string);
|
||||
if let Some(location) = location {
|
||||
location.ready_to_complete();
|
||||
}
|
||||
|
@ -236,6 +253,9 @@ where
|
|||
let old_url = mem::replace(&mut initial_state.url, url.clone());
|
||||
let old_params =
|
||||
mem::replace(&mut initial_state.params, params.clone());
|
||||
let new_matched = ArcRwSignal::new(matched_string);
|
||||
let old_matched =
|
||||
mem::replace(&mut initial_state.matched, new_matched.clone());
|
||||
|
||||
// we drop the route state here, in case there is a <Redirect/> or similar that occurs
|
||||
// while rendering either the fallback or the new route
|
||||
|
@ -247,12 +267,13 @@ where
|
|||
owner.with(|| {
|
||||
provide_context(url);
|
||||
provide_context(params_memo);
|
||||
provide_context(Matched(ArcMemo::from(new_matched)));
|
||||
EitherOf3::B(fallback())
|
||||
.rebuild(&mut state.borrow_mut().view)
|
||||
});
|
||||
}
|
||||
Some(matched) => {
|
||||
let (view, child) = matched.into_view_and_child();
|
||||
Some(new_match) => {
|
||||
let (view, child) = new_match.into_view_and_child();
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
if child.is_some() {
|
||||
|
@ -269,6 +290,9 @@ where
|
|||
async move {
|
||||
provide_context(url);
|
||||
provide_context(params_memo);
|
||||
provide_context(Matched(ArcMemo::from(
|
||||
new_matched,
|
||||
)));
|
||||
let view =
|
||||
if let Some(set_is_routing) = set_is_routing {
|
||||
set_is_routing.set(true);
|
||||
|
@ -296,6 +320,7 @@ where
|
|||
drop(old_owner);
|
||||
drop(old_params);
|
||||
drop(old_url);
|
||||
drop(old_matched);
|
||||
}
|
||||
})
|
||||
}));
|
||||
|
@ -349,16 +374,23 @@ where
|
|||
.map(|n| n.to_params().into_iter().collect::<ParamsMap>())
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
let matched = ArcRwSignal::new(
|
||||
new_match
|
||||
.as_ref()
|
||||
.map(|n| n.as_matched().to_owned())
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
let params_memo = ArcMemo::from(params.clone());
|
||||
let view = match new_match {
|
||||
None => Either::Left((self.fallback)()),
|
||||
Some(matched) => {
|
||||
let (view, _) = matched.into_view_and_child();
|
||||
Some(new_match) => {
|
||||
let (view, _) = new_match.into_view_and_child();
|
||||
let view = owner
|
||||
.with(|| {
|
||||
ScopedFuture::new(async move {
|
||||
provide_context(url);
|
||||
provide_context(params_memo);
|
||||
provide_context(Matched(ArcMemo::from(matched)));
|
||||
view.choose().await
|
||||
})
|
||||
})
|
||||
|
@ -491,6 +523,12 @@ where
|
|||
// we always need to match the new route
|
||||
let new_match = routes.match_route(current_url.path());
|
||||
let id = new_match.as_ref().map(|n| n.as_id());
|
||||
let matched = ArcRwSignal::new(
|
||||
new_match
|
||||
.as_ref()
|
||||
.map(|n| n.as_matched().to_owned())
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
|
||||
// create default starting points for owner, url, path, and params
|
||||
// these will be held in state so that future navigations can update or replace them
|
||||
|
@ -514,9 +552,10 @@ where
|
|||
params,
|
||||
path,
|
||||
url,
|
||||
matched,
|
||||
})),
|
||||
Some(matched) => {
|
||||
let (view, child) = matched.into_view_and_child();
|
||||
Some(new_match) => {
|
||||
let (view, child) = new_match.into_view_and_child();
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
if child.is_some() {
|
||||
|
@ -528,9 +567,11 @@ where
|
|||
let mut view = Box::pin(owner.with(|| {
|
||||
ScopedFuture::new({
|
||||
let url = url.clone();
|
||||
let matched = matched.clone();
|
||||
async move {
|
||||
provide_context(params_memo);
|
||||
provide_context(url);
|
||||
provide_context(Matched(ArcMemo::from(matched)));
|
||||
view.choose().await
|
||||
}
|
||||
})
|
||||
|
@ -545,6 +586,7 @@ where
|
|||
params,
|
||||
path,
|
||||
url,
|
||||
matched,
|
||||
})),
|
||||
None => {
|
||||
// see comment at the top of this function
|
||||
|
|
Loading…
Reference in a new issue