sycamore-rs / sycamore

A library for creating reactive web apps in Rust and WebAssembly
https://sycamore-rs.netlify.app
MIT License
2.79k stars 148 forks source link

Shared data update failed when nested routing layout #650

Closed ys2rice2yangsong closed 9 months ago

ys2rice2yangsong commented 9 months ago

Describe the bug

The routing layout shared data is not updated, while the shared data on other pages is updated

To Reproduce Steps to reproduce the behavior:

code:

[component]

pub fn App(cx: Scope) -> View { let model = create_signal(cx, SystemModel::new());

provide_context_ref(cx, model);

view!{
    cx,
    Router(integration=HistoryIntegration::new(),
    view = |cx, route: &ReadSignal<TopRoute>| {

        match route.get().as_ref() {
            //TopRoute::Login => view!{cx, Login{}},
            TopRoute::NotFound => view!{cx, NotFound{}},
            TopRoute::DashboardRoute(dashboard) => {
                match dashboard {
                    Dashboard::Home => view!{
                        cx,
                        MainLayout{
                            Home{}
                        }
                    },
                    Dashboard::NotFound => view!{cx, NotFound{}}
                }
            },
            _=> view!{cx, Switch(route=route)}
        }
    })
}

}

[component(inline_props)]

fn Switch<'a,G: Html>(cx: Scope<'a>, route: &'a ReadSignal) -> View { view!{ cx, ( match route.get().asref() { TopRoute::Login => view!{cx, Login{}}, => view!{cx,} } ) } }

[component]

pub fn MainLayout<'a, G: Html>(cx: Scope<'a>, children: MainLayoutProps<'a,G>) -> View { let systemModel = use_context::<Signal>(cx); let child = children.children.call(cx);

let systemTheme = systemModel.get().getSystemTheme();
console!(systemModel.get().is_hide_left.to_string());
view!{
    cx,
    link(
        rel="stylesheet",
        href = "/css/okadmin.css"
    )
    div(
        class="layui-layout-body"
    ){
        div (
            class=systemTheme
        ){
            Header{}
            LeftSidebar{}
            div(class="content-body"){
                (child)
            }
        }

    }
}

}

[component]

pub fn Header<'a, G: Html>(cx: Scope) -> View { let mut systemModel = use_context::<Signal>(cx);

let toogleMenu = move |e| {
    systemModel.modify().is_hide_left = true;
} 
....

}

======================================

Expected behavior A clear and concise description of what you expected to happen.

Screenshots If applicable, add screenshots to help explain your problem.

Environment

Additional context Add any other context about the problem here.

lukechu10 commented 9 months ago

The view function passed to Router is only called once. You need to put the entire match statement inside a view! { (match ...) } to make it reactive.