Skip to content

Commit

Permalink
basic draft for actionview-component integration
Browse files Browse the repository at this point in the history
- Allows updating of specific component without replacing entire
  dom

- could also work without components with selector argument

- in the future, probably a new class that can be
  subclassed can be made available like
  StimulsComponent or so.

- For now, the Reflex class must implement the rendered_component and
  selector methdos, though selector can be left to nil if the entire
  body is to be replaced
  • Loading branch information
effkay committed Aug 30, 2019
1 parent 36b81b2 commit 91f855b
Showing 1 changed file with 23 additions and 6 deletions.
29 changes: 23 additions & 6 deletions lib/stimulus_reflex/channel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,16 @@ def delegate_call_to_reflex(reflex, method_name, arguments = [])
end

def render_page_and_broadcast_morph(url, reflex)
html = render_page(url, reflex)
broadcast_morph url, html if html.present?
if reflex.respond_to? :rendered_component
broadcast_morph reflex.rendered_component, reflex.selector
else
html = render_page(url, reflex)
broadcast_morph html if html.present?
end
end



def render_page(url, reflex)
uri = URI.parse(url)
url_params = Rails.application.routes.recognize_path(url)
Expand Down Expand Up @@ -81,14 +87,25 @@ def render_page(url, reflex)
controller.response.body
end

def broadcast_morph(url, html)
html = extract_body_html(html)
cable_ready[stream_name].morph selector: "body", html: html, children_only: true
def broadcast_morph(html, selector = nil)
if selector.present?
html = extract_partial_html(html)
else
html = extract_body_html(html)
selector = "body"
end

cable_ready[stream_name].morph selector: selector, html: html, children_only: true
cable_ready.broadcast
end

def extract_partial_html(html)
doc = Nokogiri::HTML::DocumentFragment.parse(html)
doc.to_s
end

def extract_body_html(html)
doc = Nokogiri::HTML(html)
doc.css("body").to_s
doc.css("home").to_s
end
end

2 comments on commit 91f855b

@hopsoft
Copy link

@hopsoft hopsoft commented on 91f855b Sep 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This very looks promising! Have you run any benchmarks to see if/how this improves performance? We should see some savings with server rendering, data size over the wire, and less work on the client. Would be great to quantify the savings.

I'm also wondering if we could consolidate the internal API rather than use forking the logic. Default behavior would treat the entire page as the default component with a default selector of body. Then users could override for partial page updates. Thoughts?

@effkay
Copy link
Owner Author

@effkay effkay commented on 91f855b Sep 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback!

I had not even thought of benchmarking, since it was not my main concern, but good point, of course this will be a concern. I already went a little bit ahead from this commit, so I think in order for us to have a meaningful discussion I'll rig up a pull request (please don't feel any pressure at all that this should someday be merged, more as a conversation vehicle). I think my use case was pretty specific, and there I got what I wanted, but it might need some elaboration.

About keeping the API consistent: totally agree! My only doubt is where/how do you hook in the "selector" concept in a nice way, that's what I am not yet sure about. Anyways, let's continue in the PR.

Please sign in to comment.