-
Notifications
You must be signed in to change notification settings - Fork 76
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
Compose routes and deep nested components #59
Comments
I'm missing exactly this. I'm structuring my components just like @jgoux does, you can see a working example here: https://github.com/mrtnbroder/universal-react-webpack-boilerplate (in js) take a look at the src/Application folder, where each component exposes it's route, update, view etc. functions and where react-router consumes it at the top level. This ported to purescript-pux would be awesome! |
Routes could be composed with the -- App.purs
data AppR
= WrapRepo RepoR
| WrapDashboard DashboardR
| NotFoundR
appMatch :: Match AppR
appMatch =
WrapRepo <$> repoMatch
<|> WrapDashboard <$> dashboardMatch
<|> pure NotFoundR
-- Repo.purs
data RepoR = Repo {owner :: String, name :: String, subroute :: RepoSubR}
data RepoSubR
= Issue IssueR
| ViewFile String
repoMatch :: Match RepoR
repoMatch = lit "repo" *> (mk <$> str <*> str <*> (Issue <$> issueMatch <|> fileMatch))
where
mk owner name subroute = Repo {owner, name, subroute}
fileMatch = lit "view-file" *> (ViewFile <$> str)
-- Issue.purs
data IssueR
= New
| View Int
| List
issueMatch :: Match IssueR
issueMatch = lit "issue" *>
((lit "new" *> pure New)
<|> (lit "view" *> (View <$> int))
<|> (lit "list" *> pure List))
-- Dashboard.purs
data DashboardR = Dashboard -- TODO
dashboardMatch :: Match DashboardR
dashboardMatch = lit "dashboard" *> pure Dashboard |
With inspirations from the react router and ui-router i've come up with the following prototype: route :: ∀ e. Route AppAction AppState e
route =
Route "bla" (C.wrapManyWith navigationBar) [
Route "blub" nestedStatefulRoute [
Route "here" (const typeHereComp) [],
Route "here" (const otherComponent) []
],
Route "bar/foo" (const helloComponent) [],
Route "something" (C.wrapManyWith $ caption "Here is something") [
Mount $ map implantInApp <<< childRouter
]
]
.... Every route has a component assigned ( Finally a root-router is needed to handle the url-changed event and display/update the current active routes: main :: Eff _ Unit
main = do
url <- PuxRouter.sampleUrl
let rootComp = rootRouter route
app <- Pux.start {
initialState : init,
update: C.update rootComp,
view : C.view rootComp,
inputs: [UrlChanged <$> url]
}
PuxRouter.navigateTo "bla/blub"
Pux.renderToDOM "#app" app.html To make this work we need the concept of a component (update + view function) in pux, this is the same problem as described in #31 (Nesting arbitrary components). So i've reused https://gist.github.com/sloosch/ea98c0c58f9440903c98b952265b556e#file-component-purs Here is the working prototype in action: Is this what you were asking for? Maybe the solution described by spencerjanssen is a better fit. Hadn't time to explore it further to the point where states and actions come into play. |
Here is my proof of concept library which tackles this problem from different perspective - alternative (bidirectional - all urls are generated) routing engine: https://github.com/paluh/purescript-puxing-bob Please look into examples/multiple-components-routing for working example. Unfortunately |
Thanks all for the answers ! 👍 I like all the approaches proposed, even if I don't fully understand them (yet). Questions for @sloosch :
Questions for @spencerjanssen :
Question for all :
I also think setting up a little app showing routing capabilities of each solution would be great, so we can compare from a common ground. |
I'm archiving most of the discussion threads. If you'd like to continue the discussion I'd prefer if you posted a question on StackOverflow or Gitter. Thanks. |
Hello ✋,
I'd like to organize my application in a fractal manner.
To do so, I need to be able to declare routes locally with their corresponding component. I was able to do it in JS using react + react-router's route object.
Here is an example splitting the current page into components :
So we have this hierarchy of components for the current page
https://github.com/alexmingoia/purescript-pux/issues/new
:Application → Repository → Issues → NewIssue
The idea here is to organize these components according to their relation
Parent → Child
:We can identify "routable" components which display different children based on the current URI. If we imagine that each "routable" component consume a part of the URI as we go deep in the hierarchy we can say that :
Application
displays its childRepository
when the URI is:username/:projectname
Repository
displays its childIssues
when the URI isissues
Issues
displays its childNewIssue
when the URI isnew
and its childIssueList
when the URI is/
or `` (this case can be considered as its index route)In that way, a "routable" component just needs to care about its own part of the URI, and know nothing outside of its direct children.
For the routes definition, we could add a
Route
data type to each "routable" component definition in addition to the usualState, Action, init, update, view
.This is where I stopped, now I'm looking for a way to declare local
match
functions, consume and pass the current URI to children so I can repeat the pattern down the hierarchy. 🆘The text was updated successfully, but these errors were encountered: