Coder Social home page Coder Social logo

Comments (5)

hgzimmerman avatar hgzimmerman commented on May 12, 2024

I'm going to list out the multiple different possible implementations, and list their pros and cons.

Current

<Router>
    <Route path=route!("/a/{named}" => AComponent) />
</Router>

Pros:

  • Terse - its one line per route.
  • Compile time validation of route format.
  • Proper rejection a captured string can't be transformed to a target type in the component's props.

Cons:

  • Lacks compile-time validation on if AComponent can be created from the captured variables in Route.
  • Doesn't support arbitrary render functions, only works with components.
  • Complicated and brittle implementation.
  • Extra syntax to remember.
  • FromMatches macro is dumb -> It can't derive for Props that have Options, and must be implemented manually.

Ideal

<Router>
    <Route path=route!("/a/{named}")>
        <AComponent named = parent.matches["named"] />
    </Route>
</Router>

Pros:

  • Supports arbitrary targets, either Components, functions, or other dom elements.
  • User implements captures to props conversion, but because it is adjacent to the declaration of the matcher, it is easy to maintain.
  • Simple implementation.

Cons:

  • Relies on a feature of nested components that does not exist yet, and may not be possible. (direct access to parent's state).
  • No rejection if a captured string can't be transformed to a prop type.

Pragmatic

<Router>
    <OptionalRoute 
        path=route!("/a/{named}")
        render=|matches| {
            matches["named"]
                .try_into::<usize>()
                .map(|x| {
                    Some(html!{<AComponent number=x />})
                })
        }
    <Route path=route!("/a/{}")>
        <AComponent />
    </Route>
</Router>

Pros:

  • Supports simple nested routing, and type conversion w/rejection based routing.

Cons:

  • The optional route component is verbose, although the render function can be abstracted away, possibly derived, similar to the current implementation.
  • May not be possible to have both OptionalRoute and Route as nested children. Need to determine if using trait objects in the ChildrenWithProps<Parent, Child> is possible.

from yew_router.

hgzimmerman avatar hgzimmerman commented on May 12, 2024

For the meantime, I've settled on a modified version of the "Pragmatic" solution.
It looks as follows:

<Router>
    <Route path=route!("/a/{named}" => AComponent) />
    <Route path=route!("/a/{}")>
        <AComponent named="default" />
    </Route>
</Router>

As can be seen, the route!()'s "=> Type" section can be omitted, and will default to rendering the children instead.

While the inability to specify multiple different child elements hampered having different Route-types, sticking them both into the same Route component shouldn't be confusing.

What needs to be added now is the ability to specify an alternative rendering fn in the route!() macro than a component instantiation.

from yew_router.

hgzimmerman avatar hgzimmerman commented on May 12, 2024

An alternative rendering function to the auto-generated Component one has been added to the route!() macro:

<Router>
    <Route path=route!("/a/{named}" => AComponent) />
    <Route path=route!("/a/{named}", |matches| Some(html!{{matches["named"]}})) />
    <Route path=route!("/a/{}")>
        <AComponent named="default" />
    </Route>
</Router>

from yew_router.

hgzimmerman avatar hgzimmerman commented on May 12, 2024

I've removed a lot of the macro-specific syntax, leaving just the specification of the path matcher string. The render target is now specified by a render prop.

The above example now looks approximately like:

<Router>
    <Route path=route!("/a/{named}") render=component::<AComponent>() />
    <Route path=route!("/b/{named}")  render=Render::new(|matches: &Matches| Some(html!{{matches["named"]}})) />
    <Route path=route!("/c/{}")>
        <AComponent named="default" />
    </Route>
</Router>

from yew_router.

hgzimmerman avatar hgzimmerman commented on May 12, 2024

Design is pretty set right now and is unlikely to change much.

from yew_router.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.