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)