Class: ViewComponentReflex::Reflex

Inherits:
StimulusReflex::Reflex
  • Object
show all
Defined in:
lib/view_component_reflex/reflex.rb

Class Attribute Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object



105
106
107
108
109
110
111
112
113
# File 'lib/view_component_reflex/reflex.rb', line 105

def method_missing(name, *args)
  morph :nothing
  super unless respond_to_missing?(name)
  state.each do |k, v|
    component.instance_variable_set(k, v)
  end
  name.to_proc.call(component, *args)
  refresh! unless @prevent_refresh
end

Class Attribute Details

.component_classObject

Returns the value of attribute component_class.



5
6
7
# File 'lib/view_component_reflex/reflex.rb', line 5

def component_class
  @component_class
end

Instance Method Details

#method(name) ⇒ Object

SR’s delegate_call_to_reflex in channel.rb uses method to gather the method parameters, but since we’re abusing method_missing here, that’ll always fail



86
87
88
# File 'lib/view_component_reflex/reflex.rb', line 86

def method(name)
  component.method(name.to_sym)
end

#morph(selectors, html = "") ⇒ Object

this is copied out of stimulus_reflex/reflex.rb and modified



95
96
97
98
99
100
101
102
103
# File 'lib/view_component_reflex/reflex.rb', line 95

def morph(selectors, html = "")
  case selectors
  when :nothing
    @broadcaster = StimulusReflex::NothingBroadcaster.new(self)
  else
    @broadcaster = StimulusReflex::SelectorBroadcaster.new(self) unless broadcaster.selector?
    broadcaster.morphs << [selectors, html]
  end
end

#prevent_refresh!Object



115
116
117
# File 'lib/view_component_reflex/reflex.rb', line 115

def prevent_refresh!
  @prevent_refresh = true
end

#refresh!(primary_selector = nil, *rest) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/view_component_reflex/reflex.rb', line 8

def refresh!(primary_selector = nil, *rest)
  save_state

  if primary_selector.nil? && !component.can_render_to_string?
    primary_selector = selector
  end
  if primary_selector
    prevent_refresh!

    controller.process(params[:action])
    document = Nokogiri::HTML(controller.response.body)
    [primary_selector, *rest].each do |s|
      html = document.css(s)
      if html.present?
        CableReady::Channels.instance[stream_name].morph(
          selector: s,
          html: html.inner_html,
          children_only: true,
          permanent_attribute_name: "data-reflex-permanent",
          stimulus_reflex: {
              reflex_id: reflex_id,
              xpath: xpath,
              c_xpath: c_xpath,
              target: target,
              reflex_controller: reflex_controller,
              url: url,
              morph: :page,
              attrs: {key: element.dataset[:key]}
          }
        )
      end
    end
  else
    refresh_component!
  end
  cable_ready.broadcast
end

#refresh_all!Object



75
76
77
# File 'lib/view_component_reflex/reflex.rb', line 75

def refresh_all!
  refresh!("body")
end

#refresh_component!Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/view_component_reflex/reflex.rb', line 46

def refresh_component!
  component.tap do |k|
    k.define_singleton_method(:key) do
      element.dataset[:key]
    end
  end
  document = Nokogiri::HTML(component.render_in(controller.view_context))
  CableReady::Channels.instance[stream_name].morph(
    selector: selector,
    children_only: true,
    html: document.css(selector).inner_html,
    permanent_attribute_name: "data-reflex-permanent",
    stimulus_reflex: {
        reflex_id: reflex_id,
        xpath: xpath,
        target: target,
        c_xpath: c_xpath,
        reflex_controller: reflex_controller,
        url: url,
        morph: :page,
        attrs: {key: element.dataset[:key]}
    }
  )
end

#respond_to_missing?(name, _ = false) ⇒ Boolean

Returns:



90
91
92
# File 'lib/view_component_reflex/reflex.rb', line 90

def respond_to_missing?(name, _ = false)
  !!name.to_proc
end

#selectorObject



79
80
81
# File 'lib/view_component_reflex/reflex.rb', line 79

def selector
  "[data-controller~=\"#{stimulus_controller}\"][data-key=\"#{element.dataset[:key]}\"]"
end

#targetObject



71
72
73
# File 'lib/view_component_reflex/reflex.rb', line 71

def target
  "#{component_class}##{method_name}"
end