ux
ux copied to clipboard
[LiveComponent] Design suggestion to keep the origin route
This issue summarize a slack discussion
As already mentioned in a couple of issues usually about pagination using knp bundle, it's currently hard to create links using the same route as the origin context where a component is rendered.
A possible solution to that would be to add a trait, for example ComponentWithOriginRouteTrait like so :
trait ComponentWithRouteOriginTrait
{
#[LiveProp]
public ?string $routeName = null;
#[LiveProp]
public ?array $routeParams = [];
}
Then in a listener inject the values from the RequestStack at render time using PreCreateForRenderEvent.
As far as i understand the code, it's currently not possible to do that properly from "outside" (the app itself) for multiple reasons :
PreCreateForRenderEventonly expose the component name, not its class so we can't check if the component has the trait.ComponentFactorywho could give us the component class from its name isn't injectable.PreCreateForRenderEventis expected to take care of the rendering by defining its ownrenderedStringproperty, wich isn't ideal for this situation.
Of course given how common the issue is, i think it would be worth adding this to symfony/ux-live-component. If so, only [3] would still be annoying.
I also think it would be nice to let people do similar listeners so here is a few ideas to make it simpler :
- Either add the
ComponentMetadatain thePreCreateForRenderEventpayload. - Or simply make the
ComponentFactoryinjectable. - Give
PreCreateForRenderEventthe ability to only change the component props before it's rendered, without the need to setrenderedString.
There is an ongoing-soon-to-be-merge PR about LiveComponent and url's that should, if I understand correctly, fullfill your need : https://github.com/symfony/ux/pull/1230
There is an ongoing-soon-to-be-merge PR about LiveComponent and url's that should, if I understand correctly, fullfill your need : #1230
Maybe i don't understand the PR but it doesn't seems to give access to the origin route name and params, it adds the ability to bind url query parameters to LiveProps. Or did i miss something ?
As already mentioned in a couple of issues usually about pagination using knp bundle, it's currently hard to create links using the same route as the origin context where a component is rendered.
It will help answering this problem, as the "page" is a URL query parameter
If you want to have the route name, parameters, etc.. you can inject the RequestStack in your component as it is a service like any other.
- Either add the
ComponentMetadatain thePreCreateForRenderEventpayload.
PreCreateForRenderEvent is an internal event used only to short-circuit the entire rendering process. It cannot expose the ComponentMetadata there because the metadata is loaded after this event is dispatched.
- Or simply make the
ComponentFactoryinjectable.
I believe today the idea is to keep it @internal, because this allows changes in the implementation that would be really difficult is it was public (BC breaks..)
- Give
PreCreateForRenderEventthe ability to only change the component props before it's rendered, without the need to setrenderedString.
You can maybe take a look at the other events, i think PreRender may suit you.
Thank you for this issue. There has not been a lot of activity here for a while. Has this been resolved?
no
Thank you for this issue. There has not been a lot of activity here for a while. Has this been resolved?
Hi @jcrombez !
Some thought here:
First you need to get the information you want to store. You can
- pass
app.current_routeandapp.current_route_paramsto the component from your template - inject the Request Stack in your component constructor, ar any method : it is a service registered in the container (only this definition is "non-shared").
- write things in some meta/data- attribute in the original HTML page, and fetch it from there via a stimulus controller, an event, etc etc
Then, storing the data in the state, via a non-writable LiveProp (as you show with your trait example) seems a good method. It will be then available as you like in the following / XHR re-renders.
You have here a legit need here.. but I don't think this would be that easy to generalise, as every app has its ows sets of rules and habits regarding routing, security, etc.
There is no special way/hidden magic we could use here, that you cannot implement yourself.
Again, it can be a good idea sometimes, but i don't think we want to promote this pattern too much, making the component dependant on external context, not just the props it exposes itself, and blurry.
I'm closing here because there has been no change in the past year. You can reopen one if you thing this is a mistake.
Have a nice day