Skip to content

Commit 82f391b

Browse files
Merge branch 'develop' into issue-255
2 parents 1585b72 + f3cbba9 commit 82f391b

File tree

4 files changed

+147
-22
lines changed

4 files changed

+147
-22
lines changed

app/concepts/matestack/ui/core/component/dynamic.rb

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ def components(&block)
134134
@nodes = Matestack::Ui::Core::ComponentNode.build(self, nil, &block)
135135

136136
@nodes.each do |key, node|
137-
@cells[key] = to_cell(key, node["component_name"], node["config"], node["argument"], node["components"], node["included_config"], node["cached_params"])
137+
@cells[key] = to_cell("#{@component_key}__#{key}", node["component_name"], node["config"], node["argument"], node["components"], node["included_config"], node["cached_params"])
138138
end
139139
end
140140

@@ -167,6 +167,38 @@ def modifiers
167167
result.join(" ")
168168
end
169169

170+
def render_child_component component_key, current_search_keys_array
171+
if respond_to? :prepare
172+
prepare
173+
end
174+
175+
response
176+
177+
if current_search_keys_array.count > 1
178+
if @nodes.dig(*current_search_keys_array) == nil
179+
rest = []
180+
while @nodes.dig(*current_search_keys_array) == nil
181+
rest << current_search_keys_array.pop
182+
end
183+
node = @nodes.dig(*current_search_keys_array)
184+
cell = to_cell(component_key, node["component_name"], node["config"], node["argument"], node["components"], node["included_config"], node["cached_params"])
185+
begin
186+
return cell.render_child_component component_key, rest.reverse[1..-1]
187+
rescue
188+
return cell.render_content
189+
end
190+
else
191+
node = @nodes.dig(*current_search_keys_array)
192+
cell = to_cell(component_key, node["component_name"], node["config"], node["argument"], node["components"], node["included_config"], node["cached_params"])
193+
return cell.render_content
194+
end
195+
else
196+
node = @nodes[current_search_keys_array[0]]
197+
cell = to_cell(component_key, node["component_name"], node["config"], node["argument"], node["components"], node["included_config"], node["cached_params"])
198+
return cell.render_content
199+
end
200+
end
201+
170202
private
171203

172204
def generate_children_cells

app/concepts/matestack/ui/core/page/page.rb

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -91,23 +91,9 @@ def show(component_key=nil, only_page=false)
9191
concept(@app_class).call(:show, @page_id, @nodes)
9292
when :render_component
9393
begin
94-
if component_key.include?("__")
95-
keys_array = component_key.gsub("__", "__components__").split("__").map {|k| k.to_s}
96-
page_content_keys = keys_array.select{|key| key.match(/^page_content_/)}
97-
if page_content_keys.any?
98-
keys_array = keys_array.drop(keys_array.find_index(page_content_keys[0])+2)
99-
end
100-
node = @nodes.dig(*keys_array)
101-
cell = to_cell(component_key, node["component_name"], node["config"], node["argument"], node["components"], node["included_config"], node["cached_params"])
102-
return cell.render_content
103-
else
104-
node = @nodes[component_key]
105-
cell = to_cell(component_key, node["component_name"], node["config"], node["argument"], node["components"], node["included_config"], node["cached_params"])
106-
return cell.render_content
107-
end
108-
rescue
109-
raise "Component '#{component_key}' could not be resolved. Notice: Rerendering currently works only on page-level. \
110-
You are therefore currently not able to use 'async' within a component for example!"
94+
render_child_component component_key
95+
rescue => e
96+
raise "Component '#{component_key}' could not be resolved."
11197
end
11298
end
11399
end
@@ -116,6 +102,34 @@ def page_id
116102
@custom_page_id ||= @page_id
117103
end
118104

105+
def render_child_component component_key
106+
if component_key.include?("__")
107+
keys_array = component_key.gsub("__", "__components__").split("__").map {|k| k.to_s}
108+
page_content_keys = keys_array.select{|key| key.match(/^page_content_/)}
109+
if page_content_keys.any?
110+
keys_array = keys_array.drop(keys_array.find_index(page_content_keys[0])+2)
111+
end
112+
if @nodes.dig(*keys_array) == nil
113+
rest = []
114+
while @nodes.dig(*keys_array) == nil
115+
rest << keys_array.pop
116+
end
117+
node = @nodes.dig(*keys_array)
118+
cell = to_cell(component_key, node["component_name"], node["config"], node["argument"], node["components"], node["included_config"], node["cached_params"])
119+
return cell.render_child_component component_key, rest.reverse[1..-1]
120+
else
121+
node = @nodes.dig(*keys_array)
122+
cell = to_cell(component_key, node["component_name"], node["config"], node["argument"], node["components"], node["included_config"], node["cached_params"])
123+
return cell.render_content
124+
end
125+
else
126+
node = @nodes[component_key]
127+
cell = to_cell(component_key, node["component_name"], node["config"], node["argument"], node["components"], node["included_config"], node["cached_params"])
128+
return cell.render_content
129+
end
130+
end
131+
132+
119133
private
120134

121135
def resolve_isolated_component component_key

docs/components/async.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ As the name suggests, the async component allows us to let our components behave
66

77
Please be aware that, if not configured otherwise, the async core component does get loaded and displayed on initial pageload!
88

9-
**the async component currently only works on page-level --> we're working on it in order support the usage of async within a component [#75](https://github.com/basemate/matestack-ui-core/issues/75)**
10-
119
## Parameters
1210

1311
The async core component accepts the following parameters:

spec/usage/components/async_spec.rb

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
describe "Async Component", type: :feature, js: true do
55

6-
it "Example 1 - Rerender on event" do
6+
it "Example 1 - Rerender on event on page-level" do
77

88
class ExamplePage < Matestack::Ui::Page
99

@@ -32,7 +32,88 @@ def response
3232
expect(before_content).not_to eq(after_content)
3333
end
3434

35-
it "Example 1.1 - Rerender on event if wrapped in app" do
35+
it "Example 1.1 - Rerender on event on (nested) component-level" do
36+
37+
module Components end
38+
module Components::Some end
39+
module Components::Other end
40+
41+
class ExamplePage < Matestack::Ui::Page
42+
43+
def response
44+
components {
45+
div do
46+
custom_some_component
47+
end
48+
}
49+
end
50+
51+
end
52+
53+
class Components::Some::Component < Matestack::Ui::StaticComponent
54+
55+
def response
56+
components {
57+
div id: "static-content-on-component" do
58+
plain "Component 1: #{DateTime.now.strftime('%Q')}"
59+
end
60+
async rerender_on: "my_event" do
61+
div id: "dynamic-content-on-component" do
62+
plain "Component 1: #{DateTime.now.strftime('%Q')}"
63+
end
64+
end
65+
async rerender_on: "my_other_event" do
66+
custom_other_component
67+
div id: "other-dynamic-content-on-component" do
68+
plain "Component 1: #{DateTime.now.strftime('%Q')}"
69+
end
70+
end
71+
}
72+
end
73+
74+
end
75+
76+
class Components::Other::Component < Matestack::Ui::StaticComponent
77+
78+
def response
79+
components {
80+
div id: "static-content-on-other-component" do
81+
plain "Component 2: #{DateTime.now.strftime('%Q')}"
82+
end
83+
async rerender_on: "my_event" do
84+
div id: "dynamic-content-on-other-component" do
85+
plain "Component 2: #{DateTime.now.strftime('%Q')}"
86+
end
87+
end
88+
async rerender_on: "my_other_event" do
89+
div id: "other-dynamic-content-on-other-component" do
90+
plain "Component 2: #{DateTime.now.strftime('%Q')}"
91+
end
92+
end
93+
}
94+
end
95+
96+
end
97+
98+
99+
visit "/example"
100+
101+
static_content_before = page.find("#static-content-on-component").text
102+
dynamic_content_before = page.find("#dynamic-content-on-component").text
103+
other_dynamic_content_before = page.find("#other-dynamic-content-on-component").text
104+
105+
page.execute_script('MatestackUiCore.matestackEventHub.$emit("my_event")')
106+
# sleep
107+
static_content_after = page.find("#static-content-on-component").text
108+
dynamic_content_after = page.find("#dynamic-content-on-component").text
109+
other_dynamic_content_after = page.find("#other-dynamic-content-on-component").text
110+
111+
expect(static_content_before).to eq(static_content_after)
112+
expect(dynamic_content_before).not_to eq(dynamic_content_after)
113+
expect(other_dynamic_content_before).to eq(other_dynamic_content_after)
114+
end
115+
116+
it "Example 1.2 - Rerender on event on page-level if wrapped in app" do
36117

37118
class Apps::ExampleApp < Matestack::Ui::App
38119

0 commit comments

Comments
 (0)