Module: Glimmer::DataBinding::ObservableArray
- Includes:
- Observable
- Defined in:
- lib/glimmer/data_binding/observable_array.rb
Defined Under Namespace
Classes: Notifier
Instance Method Summary collapse
- #<<(element) ⇒ Object (also: #push, #append)
- #[]=(index, value) ⇒ Object
- #add_element_observer(element, observer, options = {}) ⇒ Object
- #add_element_observers(element, general_options = {}) ⇒ Object
- #add_observer(observer, *args) ⇒ Object
- #array_object_observer_for(object) ⇒ Object
- #clear ⇒ Object
- #collect!(&block) ⇒ Object (also: #map!)
- #compact! ⇒ Object
- #delete(element) ⇒ Object
- #delete_at(index) ⇒ Object
- #delete_if(&block) ⇒ Object
- #element_properties_for(observer) ⇒ Object
- #ensure_array_object_observer(object, options) ⇒ Object
- #filter!(&block) ⇒ Object
- #flatten!(level = nil) ⇒ Object
- #has_observer?(observer) ⇒ Boolean
- #has_observer_element_properties?(observer, element_properties) ⇒ Boolean
- #notify_observers ⇒ Object
- #observer_element_properties ⇒ Object
- #pop ⇒ Object
- #property_observer_list ⇒ Object
- #reject!(&block) ⇒ Object
- #remove_element_observer(element, observer) ⇒ Object
- #remove_element_observers(element) ⇒ Object
- #remove_observer(observer, *args) ⇒ Object
- #replace(other_array) ⇒ Object
- #reverse! ⇒ Object
- #rotate!(count = 1) ⇒ Object
- #select!(&block) ⇒ Object
- #shift ⇒ Object
- #shuffle!(hash = nil) ⇒ Object
- #slice!(arg1, arg2 = nil) ⇒ Object
- #sort!(&block) ⇒ Object
- #sort_by!(&block) ⇒ Object
- #uniq!(&block) ⇒ Object
- #unregister_dependent_observers(old_value) ⇒ Object (also: #deregister_dependent_observers)
- #unshift(element) ⇒ Object (also: #prepend)
Methods included from Observable
Instance Method Details
#<<(element) ⇒ Object Also known as: push, append
153 154 155 156 157 158 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 153 def <<(element) super(element).tap do add_element_observers(element) notify_observers end end |
#[]=(index, value) ⇒ Object
162 163 164 165 166 167 168 169 170 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 162 def []=(index, value) old_value = self[index] unregister_dependent_observers(old_value) remove_element_observers(old_value) add_element_observers(value) super(index, value).tap do notify_observers end end |
#add_element_observer(element, observer, options = {}) ⇒ Object
68 69 70 71 72 73 74 75 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 68 def add_element_observer(element, observer, = {}) element_properties_for(observer).each do |property| observer.observe(element, property, ) end if element.is_a?(Array) && ([:recursive] == true || ([:recursive].is_a?(Integer) && [:recursive] >= 0)) ensure_array_object_observer(element, ) end end |
#add_element_observers(element, general_options = {}) ⇒ Object
62 63 64 65 66 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 62 def add_element_observers(element, = {}) property_observer_list.each do |observer, | add_element_observer(element, observer, .merge()) end end |
#add_observer(observer, *args) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 48 def add_observer(observer, *args) = args.last.is_a?(Hash) ? args.pop : {} element_properties = args.flatten.compact.uniq return observer if has_observer?(observer) && has_observer_element_properties?(observer, element_properties) property_observer_list[observer] = observer_element_properties[observer] = Concurrent::Set.new(Concurrent::Array.new(element_properties_for(observer).to_a) + Concurrent::Array.new(element_properties)) # converting to Array as a workaround to jruby-9.3.2.0 issue TODO remove this workaround when no longer needed if !.empty? && [:recursive].is_a?(Integer) = .clone [:recursive] = [:recursive] - 1 end each { |element| add_element_observer(element, observer, ) } observer end |
#array_object_observer_for(object) ⇒ Object
87 88 89 90 91 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 87 def array_object_observer_for(object) @array_object_observers ||= Concurrent::Hash.new @array_object_observers[object] = Notifier.new(self) unless @array_object_observers.has_key?(object) @array_object_observers[object] end |
#clear ⇒ Object
222 223 224 225 226 227 228 229 230 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 222 def clear each do |old_value| unregister_dependent_observers(old_value) remove_element_observers(old_value) end super.tap do notify_observers end end |
#collect!(&block) ⇒ Object Also known as: map!
238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 238 def collect!(&block) if block_given? each do |old_value| unregister_dependent_observers(old_value) remove_element_observers(old_value) end super(&block).tap do each { |element| add_element_observers(element) } notify_observers end else super end end |
#compact! ⇒ Object
254 255 256 257 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 254 def compact! # TODO consider checking which exact indices changed and only notifying if there is a change super.tap { notify_observers } end |
#delete(element) ⇒ Object
190 191 192 193 194 195 196 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 190 def delete(element) unregister_dependent_observers(element) remove_element_observers(element) super(element).tap do notify_observers end end |
#delete_at(index) ⇒ Object
198 199 200 201 202 203 204 205 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 198 def delete_at(index) old_value = self[index] unregister_dependent_observers(old_value) remove_element_observers(old_value) super(index).tap do notify_observers end end |
#delete_if(&block) ⇒ Object
207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 207 def delete_if(&block) if block_given? old_array = Array.new(self) super(&block).tap do |new_array| (old_array - new_array).each do |element| unregister_dependent_observers(element) remove_element_observers(element) end notify_observers end else super end end |
#element_properties_for(observer) ⇒ Object
145 146 147 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 145 def element_properties_for(observer) observer_element_properties[observer] ||= Concurrent::Set.new end |
#ensure_array_object_observer(object, options) ⇒ Object
77 78 79 80 81 82 83 84 85 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 77 def ensure_array_object_observer(object, ) return unless object&.is_a?(Array) array_object_observer = array_object_observer_for(object) array_observer_registration = array_object_observer.observe(object, ) property_observer_list.each do |observer, | my_registration = observer.registration_for(self) observer.add_dependent(my_registration => array_observer_registration) end end |
#filter!(&block) ⇒ Object
289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 289 def filter!(&block) if block_given? old_array = Array.new(self) super(&block).tap do (old_array - self).each do |old_value| unregister_dependent_observers(old_value) remove_element_observers(old_value) end notify_observers end else super end end |
#flatten!(level = nil) ⇒ Object
259 260 261 262 263 264 265 266 267 268 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 259 def flatten!(level=nil) each do |old_value| unregister_dependent_observers(old_value) remove_element_observers(old_value) end (level.nil? ? super() : super(level)).tap do each { |element| add_element_observers(element) } notify_observers end end |
#has_observer?(observer) ⇒ Boolean
129 130 131 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 129 def has_observer?(observer) property_observer_list.keys.include?(observer) end |
#has_observer_element_properties?(observer, element_properties) ⇒ Boolean
133 134 135 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 133 def has_observer_element_properties?(observer, element_properties) element_properties_for(observer).to_a.include_all?(*element_properties) end |
#notify_observers ⇒ Object
149 150 151 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 149 def notify_observers property_observer_list.to_a.each { |obs, opt| obs.call(self) } end |
#observer_element_properties ⇒ Object
141 142 143 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 141 def observer_element_properties @observer_element_properties ||= Concurrent::Hash.new end |
#pop ⇒ Object
172 173 174 175 176 177 178 179 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 172 def pop popped_element = last unregister_dependent_observers(popped_element) remove_element_observers(popped_element) super.tap do notify_observers end end |
#property_observer_list ⇒ Object
137 138 139 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 137 def property_observer_list @property_observer_list ||= Concurrent::Hash.new end |
#reject!(&block) ⇒ Object
346 347 348 349 350 351 352 353 354 355 356 357 358 359 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 346 def reject!(&block) if block.nil? super else old_array = Array.new(self) super(&block).tap do (old_array - self).each do |old_value| unregister_dependent_observers(old_value) remove_element_observers(old_value) end notify_observers end end end |
#remove_element_observer(element, observer) ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 116 def remove_element_observer(element, observer) element_properties_for(observer).each do |property| observer.unobserve(element, property) end if element.is_a?(ObservableArray) array_object_observer_for(element).unobserve(element) element.property_observer_list.select {|obs, opt| obs.respond_to?(:observable_array) && obs.observable_array == self}.each do |o| o.deregister_all_observables if o.respond_to?(:deregister_all_observables) @array_object_observers.reject! {|k, v| v == o} end end end |
#remove_element_observers(element) ⇒ Object
110 111 112 113 114 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 110 def remove_element_observers(element) property_observer_list.each do |observer, | remove_element_observer(element, observer) end end |
#remove_observer(observer, *args) ⇒ Object
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 93 def remove_observer(observer, *args) = args.last.is_a?(Hash) ? args.pop : {} element_properties = args element_properties = element_properties.flatten.compact.uniq if !element_properties.empty? old_element_properties = element_properties_for(observer) observer_element_properties[observer] = Concurrent::Set.new(Concurrent::Array.new(element_properties_for(observer).to_a) - Concurrent::Array.new(element_properties)) # TODO remove this workaround when no longer needed (it is for jruby-9.3.2.0 issue) each { |element| element_properties.each { |property| observer.unobserve(element, property) } } end if element_properties_for(observer).empty? property_observer_list.delete(observer) observer_element_properties.delete(observer) each { |element| remove_element_observer(element, observer) } end observer end |
#replace(other_array) ⇒ Object
361 362 363 364 365 366 367 368 369 370 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 361 def replace(other_array) old_array = Array.new(self) super(other_array).tap do (old_array - self).each do |old_value| unregister_dependent_observers(old_value) remove_element_observers(old_value) end notify_observers end end |
#reverse! ⇒ Object
232 233 234 235 236 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 232 def reverse! super.tap do notify_observers end end |
#rotate!(count = 1) ⇒ Object
270 271 272 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 270 def rotate!(count=1) super(count).tap { notify_observers } end |
#select!(&block) ⇒ Object
274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 274 def select!(&block) if block_given? old_array = Array.new(self) super(&block).tap do (old_array - self).each do |old_value| unregister_dependent_observers(old_value) remove_element_observers(old_value) end notify_observers end else super end end |
#shift ⇒ Object
181 182 183 184 185 186 187 188 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 181 def shift shifted_element = first unregister_dependent_observers(shifted_element) remove_element_observers(shifted_element) super.tap do notify_observers end end |
#shuffle!(hash = nil) ⇒ Object
304 305 306 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 304 def shuffle!(hash = nil) (hash.nil? ? super() : super(random: hash[:random])).tap { notify_observers } end |
#slice!(arg1, arg2 = nil) ⇒ Object
308 309 310 311 312 313 314 315 316 317 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 308 def slice!(arg1, arg2=nil) old_array = Array.new(self) (arg2.nil? ? super(arg1) : super(arg1, arg2)).tap do (old_array - self).each do |old_value| unregister_dependent_observers(old_value) remove_element_observers(old_value) end notify_observers end end |
#sort!(&block) ⇒ Object
319 320 321 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 319 def sort!(&block) (block.nil? ? super() : super(&block)).tap { notify_observers } end |
#sort_by!(&block) ⇒ Object
323 324 325 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 323 def sort_by!(&block) (block.nil? ? super() : super(&block)).tap { notify_observers } end |
#uniq!(&block) ⇒ Object
327 328 329 330 331 332 333 334 335 336 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 327 def uniq!(&block) each do |old_value| unregister_dependent_observers(old_value) remove_element_observers(old_value) end (block.nil? ? super() : super(&block)).tap do each { |element| add_element_observers(element) } notify_observers end end |
#unregister_dependent_observers(old_value) ⇒ Object Also known as: deregister_dependent_observers
372 373 374 375 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 372 def unregister_dependent_observers(old_value) return unless old_value.is_a?(ObservableModel) || old_value.is_a?(ObservableArray) property_observer_list.each { |observer, | observer.unregister_dependents_with_observable(observer.registration_for(self), old_value) } end |
#unshift(element) ⇒ Object Also known as: prepend
338 339 340 341 342 343 |
# File 'lib/glimmer/data_binding/observable_array.rb', line 338 def unshift(element) super(element).tap do add_element_observers(element) notify_observers end end |