fix: successfully pass context to nested routes via <Outlet/> (#447)

This commit is contained in:
Greg Johnston 2023-02-02 21:00:32 -05:00 committed by GitHub
parent f698f8badd
commit 05277f03b6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 19 additions and 8 deletions

View file

@ -83,6 +83,17 @@ impl Scope {
self.id
}
/// Returns the chain of scope IDs beginning with this one, going to its parent, grandparents, etc.
pub fn ancestry(&self) -> Vec<ScopeId> {
let mut ids = vec![self.id];
let mut cx = *self;
while let Some(parent) = cx.parent() {
ids.push(parent.id());
cx = parent;
}
ids
}
/// Creates a child scope and runs the given function within it, returning a handle to dispose of it.
///
/// The child scope has its own lifetime and disposer, but will be disposed when the parent is

View file

@ -27,7 +27,7 @@ pub fn Outlet(cx: Scope) -> impl IntoView {
}
is_showing.set(Some((child.id(), child.cx())));
provide_context(child.cx(), child.clone());
set_outlet.set(Some(child.outlet().into_view(cx)))
set_outlet.set(Some(child.outlet(cx).into_view(cx)))
}
}
});

View file

@ -104,7 +104,7 @@ impl RouteContext {
path: RefCell::new(path),
original_path: route.original_path.to_string(),
params,
outlet: Box::new(move || Some(element(cx))),
outlet: Box::new(move |cx| Some(element(cx))),
}),
})
}
@ -155,7 +155,7 @@ impl RouteContext {
path: RefCell::new(path.to_string()),
original_path: path.to_string(),
params: create_memo(cx, |_| ParamsMap::new()),
outlet: Box::new(move || fallback.as_ref().map(move |f| f(cx))),
outlet: Box::new(move |cx| fallback.as_ref().map(move |f| f(cx))),
}),
}
}
@ -171,8 +171,8 @@ impl RouteContext {
}
/// The view associated with the current route.
pub fn outlet(&self) -> impl IntoView {
(self.inner.outlet)()
pub fn outlet(&self, cx: Scope) -> impl IntoView {
(self.inner.outlet)(cx)
}
}
@ -184,7 +184,7 @@ pub(crate) struct RouteContextInner {
pub(crate) path: RefCell<String>,
pub(crate) original_path: String,
pub(crate) params: Memo<ParamsMap>,
pub(crate) outlet: Box<dyn Fn() -> Option<View>>,
pub(crate) outlet: Box<dyn Fn(Scope) -> Option<View>>,
}
impl PartialEq for RouteContextInner {

View file

@ -199,7 +199,7 @@ pub fn Routes(
provide_context(cx, route_states);
route_states.with(|state| {
if state.routes.borrow().is_empty() {
Some(base_route.outlet().into_view(cx))
Some(base_route.outlet(cx).into_view(cx))
} else {
let root = state.routes.borrow();
let root = root.get(0);
@ -208,7 +208,7 @@ pub fn Routes(
}
if prev.is_none() || !root_equal.get() {
root.as_ref().map(|route| route.outlet().into_view(cx))
root.as_ref().map(|route| route.outlet(cx).into_view(cx))
} else {
prev.cloned().unwrap()
}