Class: GrandCentral::Action::DelayedDispatch

Inherits:
Object
  • Object
show all
Defined in:
lib/grand_central/action.rb

Overview

A DelayedDispatch is an object that represents a dispatch that is intended to happen later. Arguments can be provided upfront, which will be used as the first args to the action constructor when the dispatch occurs.

When you ‘call` the DelayedDispatch, the arguments given to `call` are used as the remaining arguments to the action constructor. The action is created and dispatched to the specified store.

If you’re familiar with functional programming, this is really just a curried ‘Action.call`, where the currying only happens once.

Instance Method Summary collapse

Constructor Details

#initialize(action_class, store, args) ⇒ DelayedDispatch

Returns a new instance of DelayedDispatch.



67
68
69
70
71
72
73
74
75
# File 'lib/grand_central/action.rb', line 67

def initialize action_class, store, args
  @action_class = action_class
  @store = store
  @args = args

  if store.nil?
    raise ArgumentError, "No store set for #{action_class}"
  end
end

Instance Method Details

#[](*args) ⇒ Object



81
82
83
# File 'lib/grand_central/action.rb', line 81

def [] *args
  self.class.new @action_class, @store, @args + args
end

#call(*args) ⇒ Object



77
78
79
# File 'lib/grand_central/action.rb', line 77

def call *args
  @store.dispatch @action_class.new(*handle_bowser_event(@args + args))
end

#handle_bowser_event(args) ⇒ Object

Add support for Bowser::Event args. This is so that front-end apps can handle DOM events in a much more convenient way.



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/grand_central/action.rb', line 91

def handle_bowser_event args
  unless RUBY_ENGINE == 'opal'
    return args
  end

  args.map do |arg|
    if arg.class.name == 'Bowser::Event'
      event = arg

      case event.type
      when 'submit'
        # We're modifying a value we received, which is usually a no-no, but
        # in this case it's the most pragmatic solution I can think of.
        event.prevent
        event
      when 'input'
        event.target.value
      when 'change'
        element = event.target

        # In hindsight, using Element#type for the tag type was a bad idea.
        # It means we need to dip into JS to get the damn type property.
        if element.type == 'input' && `#{element.to_n}.type` == 'checkbox'
          element.checked?
        else
          element.value
        end
      else
        arg
      end
    else
      arg
    end
  end
end

#to_procObject



85
86
87
# File 'lib/grand_central/action.rb', line 85

def to_proc
  proc { |*args| call *args.flatten(1) }
end