Skip to content

Commit ea297e3

Browse files
authored
Merge pull request #100 from basemate/implementing_issue_58
Implementing issue 58 - Added Async Defer Feature
2 parents 43e7324 + 652cdaa commit ea297e3

File tree

8 files changed

+351
-14
lines changed

8 files changed

+351
-14
lines changed

app/concepts/matestack/ui/core/async/async.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,16 @@ const componentDef = {
1818
methods: {
1919
show: function(event_data){
2020
const self = this
21+
if (this.showing === true){
22+
return
23+
}
2124
this.showing = true
2225
this.event.data = event_data
26+
if(this.componentConfig["defer"] != undefined){
27+
if(!isNaN(this.componentConfig["defer"])){
28+
this.startDefer()
29+
}
30+
}
2331
if(this.componentConfig["hide_after"] != undefined){
2432
self.hide_after_timeout = setTimeout(function () {
2533
self.hide()
@@ -29,6 +37,12 @@ const componentDef = {
2937
hide: function(){
3038
this.showing = false
3139
this.event.data = {}
40+
},
41+
startDefer: function(){
42+
const self = this
43+
setTimeout(function () {
44+
self.rerender()
45+
}, parseInt(this.componentConfig["defer"]));
3246
}
3347
},
3448
created: function () {
@@ -39,8 +53,12 @@ const componentDef = {
3953
if(this.componentConfig["show_on"] != undefined){
4054
this.showing = false
4155
}
42-
if(this.componentConfig["hide_on"] != undefined){
43-
this.showing = true
56+
if(this.componentConfig["defer"] != undefined){
57+
if(!isNaN(this.componentConfig["defer"])){
58+
if (this.componentConfig["show_on"] == undefined){
59+
this.startDefer()
60+
}
61+
}
4462
}
4563
},
4664
beforeDestroy: function() {

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def prepare
4848
end
4949

5050
def components(&block)
51-
@nodes = Matestack::Ui::Core::PageNode.build(self, nil, &block)
51+
@nodes = Matestack::Ui::Core::PageNode.build(self, nil, context[:params], &block)
5252
end
5353

5454
def nodes_to_cell
@@ -59,12 +59,10 @@ def nodes_to_cell
5959

6060
def partial(&block)
6161
return block
62-
# Matestack::Ui::Core::PageNode.build(self, included, &block)
6362
end
6463

6564
def slot(&block)
66-
# return block
67-
Matestack::Ui::Core::PageNode.build(self, nil, &block)
65+
Matestack::Ui::Core::PageNode.build(self, nil, context[:params], &block)
6866
end
6967

7068

app/lib/matestack/ui/core/page_node.rb

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
module Matestack::Ui::Core
22
class PageNode
33

4-
def self.build(page_instance, included_config, &block)
5-
node = PageNode.new(page_instance, included_config)
4+
def self.build(page_instance, included_config, url_params, &block)
5+
node = PageNode.new(page_instance, included_config, url_params)
66
node.instance_eval(&block)
77
node.hash
88
end
99

1010
attr_reader :hash
1111

12-
def initialize(page_instance, included_config)
12+
def initialize(page_instance, included_config, url_params)
1313
@hash = {}
1414
@node_start_id = 0
1515
@included_config = included_config
16+
@url_params = url_params
1617
@page_instance = page_instance
1718
page_instance.instance_variables.each do |page_instance_var_key|
1819
self.instance_variable_set(page_instance_var_key, page_instance.instance_variable_get(page_instance_var_key))
@@ -45,7 +46,7 @@ def method_missing meth, *args, &block
4546
if meth == :partial
4647
partial_block = @page_instance.send(args.first, *args.drop(1))
4748
@hash[current_node]["components"] = PageNode.build(
48-
@page_instance, included, &partial_block
49+
@page_instance, included, @url_params, &partial_block
4950
)
5051
else
5152
if args.first.is_a?(Hash)
@@ -55,7 +56,15 @@ def method_missing meth, *args, &block
5556
end
5657

5758
if block_given?
58-
@hash[current_node]["components"] = PageNode.build(@page_instance, included, &block)
59+
if args.first.is_a?(Hash) && args.first[:defer].present?
60+
if @url_params.present? && @url_params[:component_key].present?
61+
@hash[current_node]["components"] = PageNode.build(@page_instance, included, @url_params, &block)
62+
else
63+
return
64+
end
65+
else
66+
@hash[current_node]["components"] = PageNode.build(@page_instance, included, @url_params, &block)
67+
end
5968
end
6069
end
6170
end

docs/components/async.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,73 @@ async hide_after: 1000 do
6666
end
6767
```
6868

69+
### Defer
70+
71+
The `defer` option may be used in two ways:
72+
73+
#### simple defer
74+
`defer: true` implies that the content of the `async` component gets requested within a separate GET request right after initial page load is done.
75+
```ruby
76+
async defer: true do
77+
div id: 'my-div' do
78+
plain 'I will be requested within a separate GET request right after initial page load is done'
79+
end
80+
end
81+
```
82+
83+
#### delayed defer
84+
`defer: 2000` means that the content of the `async` component gets requested within a separate GET request `2000ms` after initial page load is done.
85+
```ruby
86+
async defer: 2000 do
87+
div id: 'my-div' do
88+
plain 'I will be requested within a separate GET request 2000ms after initial page load is done'
89+
end
90+
end
91+
```
92+
93+
The content of an `async` component with activated `defer` behavior is not resolved within the first page load!
94+
95+
```ruby
96+
#...
97+
async defer: 1000 do
98+
some_database_data = SomeModel.some_heavy_query
99+
div id: 'my-div' do
100+
some_database_data.each do |some_instance|
101+
plain some_instance.id
102+
end
103+
end
104+
end
105+
async defer: 2000 do
106+
some_other_database_data = SomeModel.some_other_heavy_query
107+
div id: 'my-div' do
108+
some_other_database_data.each do |some_instance|
109+
plain some_instance.id
110+
end
111+
end
112+
end
113+
#...
114+
```
115+
116+
The `SomeModel.some_query` does not get executed within the first page load and only will be called within the deferred GET request. This helps us to render a complex UI with loads of heavy method calls step by step without slowing down the initial page load and rendering of simple content.
117+
118+
#### defer used with show_on and hide_on
119+
You can trigger the deferred GET request base on a client-side event fired by an `onclick` component for example.
120+
121+
```ruby
122+
onclick emit: "my_event" do
123+
button text: "show"
124+
end
125+
onclick emit: "my_other_event" do
126+
button text: "hide"
127+
end
128+
async defer: true, show_on: "my_event", hide_on: "my_other_event" do
129+
div id: 'my-div' do
130+
plain 'I will be requested within a separate GET request right after "my_event" is fired'
131+
end
132+
end
133+
```
134+
Everytime the `async` section gets shown, the content of the `async` component gets freshly fetched from the server!
135+
69136
## Examples
70137

71138
See some common use cases below:
@@ -185,3 +252,22 @@ page.execute_script('MatestackUiCore.matestackEventHub.$emit("my_event", { messa
185252
```
186253

187254
As a result, the event message gets shown _after_ our event was fired!
255+
256+
### Example 6: Deferred loading
257+
258+
On our example page, we wrap our async event around a placeholder for the event message.
259+
260+
```ruby
261+
class ExamplePage < Matestack::Ui::Page
262+
263+
def response
264+
components {
265+
async defer: true do
266+
div id: 'my-div' do
267+
plain 'I will be requested within a separate GET request right after initial page load is done'
268+
end
269+
end
270+
}
271+
end
272+
273+
end

spec/dummy/app/matestack/pages/my_app/my_first_page.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,21 @@ def response
77
div id: "some-id", class: "some-class" do
88
plain "hello from page 1"
99
end
10+
onclick emit: "test" do
11+
button text: "rerender"
12+
end
13+
async defer: 3000 do
14+
partial :my_deferred_scope
15+
end
16+
}
17+
end
18+
19+
def my_deferred_scope
20+
@count = DummyModel.all.count
21+
partial {
22+
div do
23+
plain "#{@count}"
24+
end
1025
}
1126
end
1227

0 commit comments

Comments
 (0)