lib/glimmer/data_binding/observable_array.rb in glimmer-2.3.0 vs lib/glimmer/data_binding/observable_array.rb in glimmer-2.4.0

- old
+ new

@@ -43,36 +43,38 @@ def call(new_value=nil, *extra_args) @observable_array.notify_observers end end - def add_observer(observer, *element_properties) + def add_observer(observer, *args) + options = args.last.is_a?(Hash) ? args.pop : {} + element_properties = args element_properties = element_properties.flatten.compact.uniq return observer if has_observer?(observer) && has_observer_element_properties?(observer, element_properties) property_observer_list << observer observer_element_properties[observer] = element_properties_for(observer) + Concurrent::Set.new(element_properties) - each { |element| add_element_observer(element, observer) } + each { |element| add_element_observer(element, observer, options) } observer end - def add_element_observers(element) + def add_element_observers(element, options = {}) property_observer_list.each do |observer| - add_element_observer(element, observer) + add_element_observer(element, observer, options) end end - def add_element_observer(element, observer) + def add_element_observer(element, observer, options = {}) element_properties_for(observer).each do |property| - observer.observe(element, property) + observer.observe(element, property, options) end - ensure_array_object_observer(element) if element.is_a?(Array) + ensure_array_object_observer(element, options) if options[:recursive] && element.is_a?(Array) end - def ensure_array_object_observer(object) + def ensure_array_object_observer(object, options) return unless object&.is_a?(Array) array_object_observer = array_object_observer_for(object) - array_observer_registration = array_object_observer.observe(object) + array_observer_registration = array_object_observer.observe(object, options) property_observer_list.each do |observer| my_registration = observer.registration_for(self) observer.add_dependent(my_registration => array_observer_registration) end end @@ -81,11 +83,13 @@ @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) + def remove_observer(observer, *args) + options = 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] = element_properties_for(observer) - Concurrent::Set.new(element_properties) each { |element| element_properties.each { |property| observer.unobserve(element, property) } } @@ -108,14 +112,12 @@ 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 + element.property_observer_list.select {|o| o.respond_to?(:observable_array) && o.observable_array == self}.each do |o| + o.deregister_all_observables @array_object_observers.reject! {|k, v| v == o} end end end @@ -243,9 +245,10 @@ end end alias map! collect! def compact! + # TODO consider checking which exact indices changed and only notifying if there is a change super.tap { notify_observers } end def flatten!(level=nil) each do |old_value|