volt 0.5.18 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Readme.md +14 -0
- data/VERSION +1 -1
- data/app/volt/controllers/notices_controller.rb +9 -0
- data/app/volt/tasks/live_query/data_store.rb +12 -0
- data/app/volt/tasks/live_query/live_query.rb +86 -0
- data/app/volt/tasks/live_query/live_query_pool.rb +36 -0
- data/app/volt/tasks/live_query/query_tracker.rb +95 -0
- data/app/volt/tasks/query_tasks.rb +57 -0
- data/app/volt/tasks/store_tasks.rb +4 -17
- data/lib/volt.rb +2 -0
- data/lib/volt/console.rb +1 -1
- data/lib/volt/controllers/model_controller.rb +4 -0
- data/lib/volt/extra_core/array.rb +9 -0
- data/lib/volt/extra_core/extra_core.rb +1 -0
- data/lib/volt/extra_core/hash.rb +11 -0
- data/lib/volt/extra_core/object.rb +4 -0
- data/lib/volt/models/array_model.rb +56 -0
- data/lib/volt/models/model.rb +6 -11
- data/lib/volt/models/model_helpers.rb +12 -0
- data/lib/volt/models/persistors/array_store.rb +120 -21
- data/lib/volt/models/persistors/model_identity_map.rb +12 -0
- data/lib/volt/models/persistors/model_store.rb +20 -60
- data/lib/volt/models/persistors/query/query_listener.rb +87 -0
- data/lib/volt/models/persistors/query/query_listener_pool.rb +9 -0
- data/lib/volt/models/persistors/store.rb +11 -13
- data/lib/volt/models/url.rb +1 -1
- data/lib/volt/page/bindings/attribute_binding.rb +2 -2
- data/lib/volt/page/bindings/base_binding.rb +13 -1
- data/lib/volt/page/bindings/component_binding.rb +1 -1
- data/lib/volt/page/bindings/content_binding.rb +2 -2
- data/lib/volt/page/bindings/each_binding.rb +25 -21
- data/lib/volt/page/bindings/event_binding.rb +4 -6
- data/lib/volt/page/bindings/if_binding.rb +4 -5
- data/lib/volt/page/bindings/template_binding.rb +4 -4
- data/lib/volt/page/channel.rb +0 -1
- data/lib/volt/page/document.rb +7 -0
- data/lib/volt/page/page.rb +4 -4
- data/lib/volt/page/reactive_template.rb +2 -2
- data/lib/volt/page/targets/dom_section.rb +5 -0
- data/lib/volt/page/tasks.rb +10 -40
- data/lib/volt/page/template_renderer.rb +4 -4
- data/lib/volt/reactive/events.rb +14 -0
- data/lib/volt/reactive/reactive_array.rb +17 -7
- data/lib/volt/reactive/reactive_value.rb +65 -1
- data/lib/volt/server.rb +1 -1
- data/lib/volt/server/if_binding_setup.rb +3 -1
- data/lib/volt/server/socket_connection_handler.rb +7 -5
- data/lib/volt/server/template_parser.rb +7 -7
- data/lib/volt/tasks/dispatcher.rb +3 -0
- data/lib/volt/utils/ejson.rb +9 -0
- data/lib/volt/utils/generic_counting_pool.rb +44 -0
- data/lib/volt/utils/generic_pool.rb +88 -0
- data/spec/models/reactive_array_spec.rb +43 -0
- data/spec/models/reactive_generator_spec.rb +58 -0
- data/spec/models/reactive_value_spec.rb +6 -0
- data/spec/page/bindings/content_binding_spec.rb +36 -0
- data/spec/spec_helper.rb +13 -12
- data/spec/tasks/live_query_spec.rb +20 -0
- data/spec/tasks/query_tasks.rb +10 -0
- data/spec/tasks/query_tracker_spec.rb +120 -0
- data/spec/templates/template_binding_spec.rb +16 -10
- data/spec/utils/generic_counting_pool_spec.rb +36 -0
- data/spec/utils/generic_pool_spec.rb +50 -0
- metadata +29 -5
- data/app/volt/tasks/channel_tasks.rb +0 -55
- data/spec/tasks/channel_tasks_spec.rb +0 -74
@@ -0,0 +1,87 @@
|
|
1
|
+
# The query listener is what gets notified on the backend when the results from
|
2
|
+
# a query have changed. It then will make the necessary changes to any ArrayStore's
|
3
|
+
# to get them to display the new data.
|
4
|
+
class QueryListener
|
5
|
+
def initialize(query_listener_pool, tasks, collection, query)
|
6
|
+
@query_listener_pool = query_listener_pool
|
7
|
+
@tasks = tasks
|
8
|
+
@stores = []
|
9
|
+
|
10
|
+
@collection = collection
|
11
|
+
@query = query
|
12
|
+
|
13
|
+
@listening = false
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_listener
|
17
|
+
@listening = true
|
18
|
+
@tasks.call('QueryTasks', 'add_listener', @collection, @query) do |results|
|
19
|
+
# When the initial data comes back, add it into the stores.
|
20
|
+
@stores.each do |store|
|
21
|
+
store.model.clear
|
22
|
+
results.each do |index, data|
|
23
|
+
store.add(index, data)
|
24
|
+
end
|
25
|
+
|
26
|
+
store.change_state_to(:loaded)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def add_store(store, &block)
|
32
|
+
puts "ADD STORE: #{store.inspect} - to #{self.inspect}"
|
33
|
+
@stores << store
|
34
|
+
|
35
|
+
if @listening
|
36
|
+
# We are already listening and have this model somewhere else,
|
37
|
+
# copy the data from the existing model.
|
38
|
+
store.model.clear
|
39
|
+
@stores.first.model.each_with_index do |item, index|
|
40
|
+
store.add(index, item)
|
41
|
+
end
|
42
|
+
else
|
43
|
+
# First time we've added a store, setup the listener and get
|
44
|
+
# the initial data.
|
45
|
+
add_listener
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def remove_store(store)
|
50
|
+
@stores.delete(store)
|
51
|
+
|
52
|
+
# When there are no stores left, remove the query listener from
|
53
|
+
# the pool, it can get created again later.
|
54
|
+
if @stores.size == 0
|
55
|
+
puts "OM"
|
56
|
+
@query_listener_pool.remove(@collection, @query)
|
57
|
+
puts "PM"
|
58
|
+
|
59
|
+
# Stop listening
|
60
|
+
if @listening
|
61
|
+
@listening = false
|
62
|
+
puts "TOTAL REMOVE"
|
63
|
+
@tasks.call('QueryTasks', 'remove_listener', @collection, @query)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def added(index, data)
|
69
|
+
@stores.each do |store|
|
70
|
+
store.add(index, data)
|
71
|
+
end
|
72
|
+
puts "Added: #{index} - #{data.inspect}"
|
73
|
+
end
|
74
|
+
|
75
|
+
def removed(ids)
|
76
|
+
@stores.each do |store|
|
77
|
+
store.remove(ids)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def changed(model_id, data)
|
82
|
+
$loading_models = true
|
83
|
+
puts "From Backend: UPDATE: #{model_id} with #{data.inspect}"
|
84
|
+
Persistors::ModelStore.changed(model_id, data)
|
85
|
+
$loading_models = false
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'volt/utils/generic_pool'
|
2
|
+
require 'volt/models/persistors/query/query_listener'
|
3
|
+
|
4
|
+
# Keeps track of all query listeners, so they can be reused in different
|
5
|
+
# places. Dynamically generated queries may end up producing the same
|
6
|
+
# query in different places. This makes it so we only need to track a
|
7
|
+
# single query at once. Data updates will only be sent once as well.
|
8
|
+
class QueryListenerPool < GenericPool
|
9
|
+
end
|
@@ -1,23 +1,21 @@
|
|
1
1
|
require 'volt/models/persistors/base'
|
2
|
+
require 'volt/models/persistors/model_identity_map'
|
2
3
|
|
3
4
|
module Persistors
|
4
5
|
class Store < Base
|
5
|
-
def initialize(model, tasks=nil)
|
6
|
-
@model = model
|
7
|
-
@is_tracking = false
|
8
|
-
@tasks = tasks
|
9
|
-
end
|
10
6
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
7
|
+
@@identity_map = ModelIdentityMap.new
|
8
|
+
|
9
|
+
def initialize(model, tasks=nil)
|
10
|
+
@tasks = tasks
|
11
|
+
@model = model
|
12
|
+
|
13
|
+
@saved = false
|
19
14
|
end
|
20
15
|
|
16
|
+
def saved?
|
17
|
+
@saved
|
18
|
+
end
|
21
19
|
|
22
20
|
# On stores, we store the model so we don't have to look it up
|
23
21
|
# every time we do a read.
|
data/lib/volt/models/url.rb
CHANGED
@@ -2,9 +2,9 @@ require 'volt/page/bindings/base_binding'
|
|
2
2
|
require 'volt/page/targets/attribute_target'
|
3
3
|
|
4
4
|
class AttributeBinding < BaseBinding
|
5
|
-
def initialize(target, context, binding_name, attribute_name, getter)
|
5
|
+
def initialize(page, target, context, binding_name, attribute_name, getter)
|
6
6
|
# puts "New Attribute Binding: #{binding_name}, #{attribute_name}, #{getter}"
|
7
|
-
super(target, context, binding_name)
|
7
|
+
super(page, target, context, binding_name)
|
8
8
|
|
9
9
|
@attribute_name = attribute_name
|
10
10
|
@getter = getter
|
@@ -1,7 +1,19 @@
|
|
1
|
+
# The BaseBinding class is the base for all bindings. It takes
|
2
|
+
# 4 arguments that should be passed up from the children (via super)
|
3
|
+
#
|
4
|
+
# 1. page - this class instance should provide:
|
5
|
+
# - a #templates methods that returns a hash for templates
|
6
|
+
# - an #events methods that returns an instance of DocumentEvents
|
7
|
+
# 2. target - an DomTarget or AttributeTarget
|
8
|
+
# 3. context - the context object the binding will be evaluated in
|
9
|
+
# 4. binding_name - the id for the comment (or id for attributes) where the
|
10
|
+
# binding will be inserted.
|
1
11
|
class BaseBinding
|
2
12
|
attr_accessor :target, :context, :binding_name
|
3
13
|
|
4
|
-
def initialize(target, context, binding_name)
|
14
|
+
def initialize(page, target, context, binding_name)
|
15
|
+
# puts "NEW #{context.inspect} - #{self.inspect}"
|
16
|
+
@page = page
|
5
17
|
@target = target
|
6
18
|
@context = context
|
7
19
|
@binding_name = binding_name
|
@@ -25,7 +25,7 @@ class ComponentBinding < TemplateBinding
|
|
25
25
|
current_context = SubContext.new(model_with_parent, $page)
|
26
26
|
end
|
27
27
|
|
28
|
-
@current_template = TemplateRenderer.new(@target, current_context, @binding_name, full_path)
|
28
|
+
@current_template = TemplateRenderer.new(@page, @target, current_context, @binding_name, full_path)
|
29
29
|
|
30
30
|
call_ready
|
31
31
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'volt/page/bindings/base_binding'
|
2
2
|
|
3
3
|
class ContentBinding < BaseBinding
|
4
|
-
def initialize(target, context, binding_name, getter)
|
4
|
+
def initialize(page, target, context, binding_name, getter)
|
5
5
|
# puts "new content binding: #{getter}"
|
6
|
-
super(target, context, binding_name)
|
6
|
+
super(page, target, context, binding_name)
|
7
7
|
|
8
8
|
# Find the source for the content binding
|
9
9
|
@value = value_from_getter(getter)
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'volt/page/bindings/base_binding'
|
2
2
|
|
3
3
|
class EachBinding < BaseBinding
|
4
|
-
def initialize(target, context, binding_name, getter, variable_name, template_name)
|
4
|
+
def initialize(page, target, context, binding_name, getter, variable_name, template_name)
|
5
5
|
# puts "New EACH Binding"
|
6
6
|
|
7
|
-
super(target, context, binding_name)
|
7
|
+
super(page, target, context, binding_name)
|
8
8
|
|
9
9
|
@item_name = variable_name
|
10
10
|
@template_name = template_name
|
@@ -51,20 +51,8 @@ class EachBinding < BaseBinding
|
|
51
51
|
@templates[position].remove
|
52
52
|
@templates.delete_at(position)
|
53
53
|
|
54
|
-
value_obj = @value.cur
|
55
|
-
|
56
|
-
if value_obj
|
57
|
-
size = value_obj.size - 1
|
58
|
-
else
|
59
|
-
size = 0
|
60
|
-
end
|
61
|
-
|
62
|
-
# puts "Position: #{position} to #{size}"
|
63
|
-
|
64
54
|
# Removed at the position, update context for every item after this position
|
65
|
-
position
|
66
|
-
@templates[index].context.locals[:index].cur = index
|
67
|
-
end
|
55
|
+
update_indexes_after(position)
|
68
56
|
end
|
69
57
|
|
70
58
|
def item_added(position)
|
@@ -73,18 +61,34 @@ class EachBinding < BaseBinding
|
|
73
61
|
binding_name = @@binding_number
|
74
62
|
@@binding_number += 1
|
75
63
|
|
76
|
-
|
77
|
-
|
64
|
+
if position >= @templates.size
|
65
|
+
# Setup new bindings in the spot we want to insert the item
|
66
|
+
section.insert_anchor_before_end(binding_name)
|
67
|
+
else
|
68
|
+
# Insert the item before an existing item
|
69
|
+
section.insert_anchor_before(binding_name, @templates[position].binding_name)
|
70
|
+
end
|
78
71
|
|
79
72
|
index = ReactiveValue.new(position)
|
80
73
|
value = @value[index]
|
81
74
|
|
82
75
|
item_context = SubContext.new({@item_name => value, :index => index, :parent => @value}, @context)
|
83
76
|
|
84
|
-
|
85
|
-
@templates
|
86
|
-
|
87
|
-
|
77
|
+
item_template = TemplateRenderer.new(@page, @target, item_context, binding_name, @template_name)
|
78
|
+
@templates.insert(position, item_template)
|
79
|
+
|
80
|
+
update_indexes_after(position)
|
81
|
+
end
|
82
|
+
|
83
|
+
# When items are added or removed in the middle of the list, we need
|
84
|
+
# to update each templates index value.
|
85
|
+
def update_indexes_after(start_index)
|
86
|
+
size = @templates.size
|
87
|
+
if size > 0
|
88
|
+
start_index.upto(@templates.size-1) do |index|
|
89
|
+
@templates[index].context.locals[:index].cur = index
|
90
|
+
end
|
91
|
+
end
|
88
92
|
end
|
89
93
|
|
90
94
|
def update(item=nil)
|
@@ -21,10 +21,8 @@ end
|
|
21
21
|
|
22
22
|
class EventBinding < BaseBinding
|
23
23
|
attr_accessor :context, :binding_name
|
24
|
-
def initialize(target, context, binding_name, event_name, call_proc)
|
25
|
-
|
26
|
-
@context = context
|
27
|
-
@binding_name = binding_name
|
24
|
+
def initialize(page, target, context, binding_name, event_name, call_proc)
|
25
|
+
super(page, target, context, binding_name)
|
28
26
|
@event_name = event_name
|
29
27
|
|
30
28
|
handler = Proc.new do |js_event|
|
@@ -36,12 +34,12 @@ class EventBinding < BaseBinding
|
|
36
34
|
result = @context.instance_exec(event, &call_proc)
|
37
35
|
end
|
38
36
|
|
39
|
-
@listener =
|
37
|
+
@listener = @page.events.add(event_name, self, handler)
|
40
38
|
end
|
41
39
|
|
42
40
|
# Remove the event binding
|
43
41
|
def remove
|
44
42
|
# puts "REMOVE EL FOR #{@event}"
|
45
|
-
|
43
|
+
@page.events.remove(@event_name, self)
|
46
44
|
end
|
47
45
|
end
|
@@ -1,12 +1,11 @@
|
|
1
1
|
require 'volt/page/bindings/base_binding'
|
2
2
|
|
3
3
|
class IfBinding < BaseBinding
|
4
|
-
def initialize(target, context, binding_name, branches)
|
5
|
-
getter, template_name = branches[0]
|
4
|
+
def initialize(page, target, context, binding_name, branches)
|
6
5
|
# puts "New If Binding: #{binding_name}, #{getter.inspect}"
|
6
|
+
super(page, target, context, binding_name)
|
7
7
|
|
8
|
-
|
9
|
-
super(target, context, binding_name)
|
8
|
+
getter, template_name = branches[0]
|
10
9
|
|
11
10
|
@branches = []
|
12
11
|
@listeners = []
|
@@ -58,7 +57,7 @@ class IfBinding < BaseBinding
|
|
58
57
|
end
|
59
58
|
|
60
59
|
if true_template
|
61
|
-
@template = TemplateRenderer.new(@target, @context, binding_name, true_template)
|
60
|
+
@template = TemplateRenderer.new(@page, @target, @context, binding_name, true_template)
|
62
61
|
end
|
63
62
|
end
|
64
63
|
end
|
@@ -2,9 +2,9 @@ require 'volt/page/bindings/base_binding'
|
|
2
2
|
require 'volt/page/template_renderer'
|
3
3
|
|
4
4
|
class TemplateBinding < BaseBinding
|
5
|
-
def initialize(target, context, binding_name, binding_in_path, getter)
|
5
|
+
def initialize(page, target, context, binding_name, binding_in_path, getter)
|
6
6
|
# puts "New template binding: #{context.inspect} - #{binding_name.inspect}"
|
7
|
-
super(target, context, binding_name)
|
7
|
+
super(page, target, context, binding_name)
|
8
8
|
|
9
9
|
# Binding in path is the path for the template this binding is in
|
10
10
|
setup_path(binding_in_path)
|
@@ -40,7 +40,7 @@ class TemplateBinding < BaseBinding
|
|
40
40
|
|
41
41
|
# Returns true if there is a template at the path
|
42
42
|
def check_for_template?(path)
|
43
|
-
|
43
|
+
@page.templates[path]
|
44
44
|
end
|
45
45
|
|
46
46
|
# Takes in a lookup path and returns the full path for the matching
|
@@ -141,7 +141,7 @@ class TemplateBinding < BaseBinding
|
|
141
141
|
current_context = @context
|
142
142
|
end
|
143
143
|
|
144
|
-
@current_template = TemplateRenderer.new(@target, current_context, @binding_name, full_path)
|
144
|
+
@current_template = TemplateRenderer.new(@page, @target, current_context, @binding_name, full_path)
|
145
145
|
|
146
146
|
call_ready
|
147
147
|
end
|
data/lib/volt/page/channel.rb
CHANGED
data/lib/volt/page/page.rb
CHANGED
@@ -61,7 +61,7 @@ class Page
|
|
61
61
|
}
|
62
62
|
});
|
63
63
|
|
64
|
-
$(document).on('click', 'a', function(event) {
|
64
|
+
$(document).on('click', 'a', function(event) {
|
65
65
|
Opal.gvars.page.$link_clicked($(this).attr('href'));
|
66
66
|
event.stopPropagation();
|
67
67
|
|
@@ -141,7 +141,7 @@ class Page
|
|
141
141
|
main_controller = IndexController.new
|
142
142
|
|
143
143
|
# Setup main page template
|
144
|
-
TemplateRenderer.new(DomTarget.new, main_controller, 'CONTENT', 'home/index/index/body')
|
144
|
+
TemplateRenderer.new(self, DomTarget.new, main_controller, 'CONTENT', 'home/index/index/body')
|
145
145
|
|
146
146
|
# Setup title listener template
|
147
147
|
title_target = AttributeTarget.new
|
@@ -149,7 +149,7 @@ class Page
|
|
149
149
|
title = title_target.to_html
|
150
150
|
`document.title = title;`
|
151
151
|
end
|
152
|
-
TemplateRenderer.new(title_target, main_controller, "main", "home/index/index/title")
|
152
|
+
TemplateRenderer.new(self, title_target, main_controller, "main", "home/index/index/title")
|
153
153
|
|
154
154
|
# TODO: this dom ready should really happen in the template renderer
|
155
155
|
main_controller.dom_ready if main_controller.respond_to?(:dom_ready)
|
@@ -181,7 +181,7 @@ if Volt.client?
|
|
181
181
|
$page = Page.new
|
182
182
|
|
183
183
|
# Call start once the page is loaded
|
184
|
-
Document.ready? do
|
184
|
+
Document.ready? do
|
185
185
|
$page.start
|
186
186
|
end
|
187
187
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
class ReactiveTemplate
|
2
2
|
include Events
|
3
3
|
|
4
|
-
def initialize(context, template_path)
|
4
|
+
def initialize(page, context, template_path)
|
5
5
|
# puts "New Reactive Template: #{context.inspect} - #{template_path.inspect}"
|
6
6
|
@template_path = template_path
|
7
7
|
@target = AttributeTarget.new
|
8
|
-
@template = TemplateRenderer.new(@target, context, "main", template_path)
|
8
|
+
@template = TemplateRenderer.new(page, @target, context, "main", template_path)
|
9
9
|
end
|
10
10
|
|
11
11
|
def event_added(event, scope_provider, first)
|
@@ -47,6 +47,11 @@ class DomSection < BaseSection
|
|
47
47
|
Element.find(@end_node).before("<!-- $#{binding_name} --><!-- $/#{binding_name} -->")
|
48
48
|
end
|
49
49
|
|
50
|
+
def insert_anchor_before(binding_name, insert_after_binding)
|
51
|
+
node = find_by_comment("$#{insert_after_binding}")
|
52
|
+
Element.find(node).before("<!-- $#{binding_name} --><!-- $/#{binding_name} -->")
|
53
|
+
end
|
54
|
+
|
50
55
|
# Takes in an array of dom nodes and replaces the current content
|
51
56
|
# with the new nodes
|
52
57
|
def nodes=(nodes)
|
data/lib/volt/page/tasks.rb
CHANGED
@@ -29,19 +29,17 @@ class Tasks
|
|
29
29
|
|
30
30
|
def received_message(name, callback_id, *args)
|
31
31
|
case name
|
32
|
+
when 'added', 'removed', 'updated', 'changed'
|
33
|
+
notify_query(name, *args)
|
32
34
|
when 'response'
|
33
35
|
response(callback_id, *args)
|
34
|
-
when 'changed'
|
35
|
-
changed(*args)
|
36
|
-
when 'added'
|
37
|
-
added(*args)
|
38
|
-
when 'removed'
|
39
|
-
removed(*args)
|
40
36
|
when 'reload'
|
41
37
|
reload
|
42
38
|
end
|
43
39
|
end
|
44
40
|
|
41
|
+
# When a request is sent to the backend, it can attach a callback,
|
42
|
+
# this is called from the backend to pass to the callback.
|
45
43
|
def response(callback_id, result, error)
|
46
44
|
callback = @callbacks.delete(callback_id)
|
47
45
|
|
@@ -55,40 +53,12 @@ class Tasks
|
|
55
53
|
end
|
56
54
|
end
|
57
55
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
Persistors::
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
def added(path, data)
|
66
|
-
$loading_models = true
|
67
|
-
|
68
|
-
# Don't add if already in there
|
69
|
-
# TODO: shouldn't send twice
|
70
|
-
unless Persistors::ModelStore.from_id(data[:_id])
|
71
|
-
|
72
|
-
_, parent_id = data.find {|k,v| k != :_id && k[-3..-1] == '_id'}
|
73
|
-
if parent_id
|
74
|
-
parent_collection = Persistors::ModelStore.from_id(parent_id).model
|
75
|
-
else
|
76
|
-
# On the root
|
77
|
-
parent_collection = $page.store
|
78
|
-
end
|
79
|
-
|
80
|
-
puts "From Backend: Add: #{path.inspect} - #{data.inspect}"
|
81
|
-
parent_collection.send(path) << data
|
82
|
-
end
|
83
|
-
$loading_models = false
|
84
|
-
end
|
85
|
-
|
86
|
-
def removed(id)
|
87
|
-
puts "From Backend: Remove: #{id}"
|
88
|
-
$loading_models = true
|
89
|
-
model = Persistors::ModelStore.from_id(id)
|
90
|
-
model.delete!
|
91
|
-
$loading_models = false
|
56
|
+
# Called when the backend sends a notification to change the results of
|
57
|
+
# a query.
|
58
|
+
def notify_query(method_name, collection, query, *args)
|
59
|
+
query_obj = Persistors::ArrayStore.query_pool.lookup(collection, query)
|
60
|
+
puts "FOUND QUERY: #{collection.inspect} - #{query.inspect} - #{query_obj.inspect} - #{method_name} - #{query_obj.instance_variable_get('@stores').inspect}"
|
61
|
+
query_obj.send(method_name, *args)
|
92
62
|
end
|
93
63
|
|
94
64
|
def reload
|