Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditional rendering #19

Closed
njam opened this issue Nov 2, 2019 · 2 comments
Closed

Conditional rendering #19

njam opened this issue Nov 2, 2019 · 2 comments

Comments

@njam
Copy link

njam commented Nov 2, 2019

I'm wondering what is a good way to render dom nodes conditionally, based on a signal.

For example to render different sub pages, based on the current "route" (document.location). In such a case only the current sub page should be added the document, and when the route changes, it should be replaced.

I can use a SignalVec, with each entry representing a different state, and then render only the current state with children_signal_vec(), but it feels like a workaround.

How about adding a function that renders a dom node based on a signal, and adds it as a child to a parent node (here's a draft: #18)?
Then it could be used something like this:

html("div")
    .child_signal(state.path.signal_cloned()
        .map({
            let state = Rc::clone(self);
            move |path| {
                match path.as_str() {
                    "/foo" => {
                        html("div").text("foo page!").into_dom()
                    }
                    "/bar" => {
                        html("div").text("bar page!").into_dom()
                    }
                    _ => {
                        html("div").text("error page!").into_dom()
                    }
                }
            }
        })
    )
    .into_dom()

Or maybe there are other, better ways to solve this?

@Pauan
Copy link
Owner

Pauan commented Nov 3, 2019

The correct thing is to use children_signal_vec combined with to_signal_vec, like this:

html("div", {
    .children_signal_vec(state.path.signal_cloned()
        .map({
            let state = Rc::clone(self);
            move |path| {
                match path.as_str() {
                    "/foo" => {
                        vec![
                            html("div", {
                                .text("foo page!")
                            })
                        ]
                    }
                    "/bar" => {
                        vec![
                            html("div", {
                                .text("bar page!")
                            })
                        ]
                    }
                    _ => {
                        vec![
                            html("div", {
                                .text("error page!")
                            })
                        ]
                    }
                }
            }
        })
        .to_signal_vec())
})

Since the signal returns a Vec, this also enables you to return multiple Dom nodes (whenever the signal changes it will remove all the existing children and replace them with the new children).

@njam
Copy link
Author

njam commented Nov 3, 2019

Ah nice! I missed .to_signal_vec(). This solves the problem of course, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants