-
Notifications
You must be signed in to change notification settings - Fork 433
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
Refresh events for individual frames #1215
Comments
@rbclark That seems off to me because the refresh action which is broadcast is tied to a specific model and then views simply subscribe to refreshes from that model. The model does blind What happens now if you put a I know for sure that if the turbo_stream_from is outside of the turbo-frame, that will trigger a refreshing morph of the full page, which subsequently triggers a morphing refresh to each individual turbo-frame on the page (provided that those turbo frames have But it may be the case that if you put the turbo_stream_from inside of a turbo frame it might only refresh that frame, without having to do a special refresh broadcast which targets that frame. Give it a shot and see what happens. And if that doesn't work then maybe the base-case will still work for you to just trigger a refresh of the full page. |
@krschacht Thank you for your reply! I appreciate your perspective on this, it seems I've used For the page in question, it already heavily utilizes turbo streams and stimulus controllers. I spent most of the week investigating converting it over to morphing and came to the conclusion that it would be a significant undertaking to get it all to morph properly since the page consists of filtering, sorting, cross-page-multi-select, and expandable sections each with their own trix editor. I'm also a bit worried about the performance of this page after a full morph since I had to apply a decent amount of logic in |
Conceptually, the idea behind broadcast_refresh is "I don't want to think about what parts of the page need to be updated. Please update any parts of the page that ought to change now that I've made an update to this particular model." So the idea that it always triggers a full page morph feels appropriate. Because a full page morph may result in zero dom nodes being updates or lots of dom nodes updating. I would be surprised that morphing would mess things up. Maybe you simply need to add some "permanent" tags in the right places. But I'm still new to moprhing as well so I don't know all the edge cases with it. My app is pretty simple so far (https://github.com/the-dot-bot/hostedgpt) |
Oh, but note that once The 1192 PR gets merged in you will be able to use javascript to target any individual turbo-frame you want and call a .refresh() on it. So it would be a bit hacky, but you could wire up your own special turbo stream action which exists solely to trigger the morphing refresh of specific turbo frames. |
@krschacht I tried to document some of the gotcha’s that I think are bugs in a few of the issues I opened on this repository. A lot of the issues revolved around keeping stimulus state and things like that. There’s also some stuff that I want to be permanent in some situations and temporary in others, the app I’m working on has one very complex page in particular that is causing issues. Regarding implementing a custom turbo action, that’s my plan next week. I just figured I’d float the idea to the project as a whole since I think it’ll be useful for people other than just me! |
I think I have a similar issue as the one described by OP. Unfortunately I also needed to solve it prior to the release of turbo 8. Fwiw, I'm doing almost exactly this. It's been kinda nice! I have a custom turbo steam action called "custom_event". Then, a stimulus controller with a url value. Upon receiving the event, the controller requests the url, and the response is free to do whatever contextual thing it wants. What's nice about this is the broadcast is tiny and different parts of the page -- or other pages entirely can request different responses that perform different actions. In my case, I respond with a morph turbo stream action to update very specific parts of the page. As I mentioned, because it was prior to turbo 8, I was using the idiomorph library directly. It sounds like once #1192 lands I might be able to delete some code. For context, I really wanted the response to be as slim as possible because it's quite chatty for this near real time application. |
Now that #1192 has been merged and |
I had the same problem and solved it with a custom action. I like the idea that if the How I solved it if it can help anyone: // custom turbo action
Turbo.StreamActions.reload = function () {
// if the frame has a `src`, reload
// if not but has a data-src => load that src
// else do nothing
document.querySelectorAll(`turbo-frame#${this.target}`).forEach((frame) => {
if (frame.src) {
frame.reload();
} else if (frame.dataset.src) {
frame.src = frame.dataset.src;
}
});
}; <%# putting this outside the frame to show the broadcast of 2 events %>
<%= turbo_stream_from product %>
<%# in template, example with pre-render %>
<%= turbo_frame_tag product, refresh: "morph", data: {src: product_path(product)} %>
<% do something with `product` that maybe depends on the current user %>
<% end %>
<%# example with eager loading %>
<%= turbo_frame_tag "#{dom_id(product)}_mini}", refresh: "morph", src: mini_product_path(product) %> assuming you have setup 2 routes, # app/views/products/show.html.erb
<%# you can omit the src here if you want: %>
<%= turbo_frame_tag @product, refresh: "morph" %>
<% do something with `@product` that maybe depends on the current user %>
<% end %> # app/views/products/mini.html.erb
<%# you can also put the (data)-src here if you want/need %>
<%= turbo_frame_tag product "#{dom_id(@product)}_mini}", refresh: "morph", src: mini_product_path(@product) %>
<% do something with `@product` that maybe depends on the current user %>
<% end %> class Product < ApplicationRecord
after_commit on: :update do
reload_frames
end
def reload_frames
broadcast_action_later_to(self, action: "reload", target: "product_{self.id}", render: false)
broadcast_action_later_to(self, action: "reload", target: "product_{self.id}_mini", render: false)
end
end |
Full page morphing is very useful in a lot of situations, but for more complicated pages it would be awesome to be able to trigger refreshing for individual frames on the page. I realize this sounds very similar to what turbo streams already do, however the distinction is that everything would be loaded with the current users context since the client is triggering the refresh, something that isn't possible currently when doing a turbo broadcast.
My use case is that I have multiple pages which have very different content based on a users permissions within turbo frames. Currently it isn't possible for me to broadcast updates to these frames since they look very different for different users and I have no context of the users permissions when rendering the content when using turbo stream broadcasts.
Having the ability to specify a
<turbo-stream action="refresh" target="some_frame"></turbo-stream>
would be awesome and would make things much more possible for my use case. With the work in #1192 it seems like what I am requesting is already pretty close to possible.The text was updated successfully, but these errors were encountered: