abbic
02/20/2023, 10:10 PMPostListScreen(
sort = sort,
onPostSelected = { postId: Long ->
// The user selected a post within the PostListScreen. Generate a URL which will match
// to the PostDetails route, by using its directions to ensure the right parameters are
// provided in the URL
router.trySend(
RouterContract.Inputs.GoToDestination(
AppScreen.PostDetails
.directions()
.pathParameter("postId", postId.toString())
.build()
)
)
},
)
and that could work, in fact i do something very similar on android, but it doesnt feel idiomatic to ballast? for example if we wanted to navigate not directly from a ui click (and in fact, from what i understand of ballast, it would be weird to drive anything from the ui except an Input
anyway), but instead drive a navigation event from business logic, we would still have to pass this navigation lambda to the event handler manually.
should i provide the router through a single {}
and inject it into the event handler? maybe with an interface that only exposes navigation routes available on this screen?abbic
02/20/2023, 10:21 PMabbic
02/20/2023, 10:23 PMCasey Brooks
02/21/2023, 4:33 PMrouter.trySend()
directly from a Compose callback has no additional boilerplate, but couples the UI very tightly to the Router (as shown in your snippet). It also potentially brings logic into the UI, if the destination changes based on the state and not just the parameters given to the callback.
On the other extreme, you could model each transition explicitly as an Event and leave the EventHandler to do all interactions with the Router, including generating destination URLs. This keeps you decoupled from the Router and explicitly describes the possible transitions between screens in the Contract, but adds a lot of boilerplate.
public object SettingsContract {
public sealed class Inputs {
public object BackButtonClicked : Inputs()
public object ViewAllPostsButtonClicked : Inputs()
public data class PostItemClicked(val postId: Long) : Inputs()
}
public sealed class Events {
public object GoBack : Events()
public object GoToPostList : Events()
public data class GoToPost(val postId: Long) : Events()
}
}
A middle-ground option would be to have the InputHandler generate the destination URL, which is then sent to the EventHandler to actually be processed. This keeps the navigation requests fairly independent of the Router library as you’re just requesting navigation to a given URL, which isn’t specific to Ballast Navigation. This is the way I’m currently using the Router in my application.
public object SettingsContract {
public sealed class Inputs {
public object BackButtonClicked : Inputs()
public object ViewAllPostsButtonClicked : Inputs()
public data class PostItemClicked(val postId: Long) : Inputs()
}
public sealed class Events {
public object GoBack : Events()
public data class GoToDestination(val url: String) : Events()
}
}
Casey Brooks
02/21/2023, 4:34 PMabbic
02/22/2023, 11:51 AM