lib/glimmer/data_binding/observable_array.rb in glimmer-2.2.2 vs lib/glimmer/data_binding/observable_array.rb in glimmer-2.3.0
- old
+ new
@@ -19,18 +19,33 @@
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
require 'set'
require 'glimmer/data_binding/observable'
+require 'glimmer/data_binding/observer'
require 'array_include_methods'
using ArrayIncludeMethods
module Glimmer
module DataBinding
module ObservableArray
include Observable
+
+ class Notifier
+ include Observer
+
+ attr_reader :observable_array
+
+ def initialize(observable_array)
+ @observable_array = observable_array
+ end
+
+ def call(new_value=nil, *extra_args)
+ @observable_array.notify_observers
+ end
+ end
def add_observer(observer, *element_properties)
element_properties = element_properties.flatten.compact.uniq
return observer if has_observer?(observer) && has_observer_element_properties?(observer, element_properties)
property_observer_list << observer
@@ -47,11 +62,28 @@
def add_element_observer(element, observer)
element_properties_for(observer).each do |property|
observer.observe(element, property)
end
+ ensure_array_object_observer(element) if element.is_a?(Array)
end
+
+ 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
+
+ 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
def remove_observer(observer, *element_properties)
element_properties = element_properties.flatten.compact.uniq
if !element_properties.empty?
old_element_properties = element_properties_for(observer)
@@ -73,9 +105,18 @@
end
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 {|o| o.observable_array == self}.each do |o|
+ o.registrations.each do |registration|
+ registration.deregister
+ end
+ @array_object_observers.reject! {|k, v| v == o}
+ end
end
end
def has_observer?(observer)
property_observer_list.include?(observer)