Skip to content
This repository was archived by the owner on Oct 19, 2018. It is now read-only.

list_components_as method #159

Open
catmando opened this issue Jul 26, 2016 · 6 comments
Open

list_components_as method #159

catmando opened this issue Jul 26, 2016 · 6 comments

Comments

@catmando
Copy link
Contributor

Implement the following pattern

class Foo < React::Component::Base
   def self.my_components
     @my_components ||= []
   end
   before_mount { self.class.my_components << self } 
   after_mount { self.class.my_components.delete(self) }

with this macro

class Foo < React::Component::Base 
  list_components_as :my_components
end

You could of course implement a components method that works for all classes, but this way you only have the (slight) overhead when you really need it...

@zetachang
Copy link
Member

Could you elaborate more on how this pattern is used? Also is my_components supposed to be class variable?

@catmando
Copy link
Contributor Author

catmando commented Sep 9, 2016

pretty much says it all..

Sometimes you want to know all the components instantiated in a class.

You can do it today using before_mount/after_mount to keep track, but why not just make a method that does it.

@catmando
Copy link
Contributor Author

@catmando
Copy link
Contributor Author

Perhaps a more useful way to do this is to use an "event" approach like http://notes.jetienne.com/2011/03/22/microeventjs.html

For example:

class AForm < React::Component::Base
  include MicroEvents::Receiver
  param :name
  on_event :close do
    if state.opened!(false) # keep in mind bang methods return the current state
      state.message! "I am closing..."
      after(2) { state.message! nil }
    end
  end
  render(DIV) do
    "I am #{params.name} ".span
    if state.opened
      BUTTON { 'close me' }.on(:click) { close }
    else
      BUTTON { 'open me' }.on(:click) { state.opened! true }
    end
    state.message.span if state.message
  end
end

class App < React::Component::Base
  render(DIV) do
    AForm(name: 'form 1')
    AForm(name: 'form 2')
    BUTTON { 'Close All' }.on(:click) { MicroEvent.close }
  end
end

@zetachang
Copy link
Member

I actually like this MicroEvents pattern more. It decouples the App from AForm, and makes it quite easy to handle the situation when multiple part of component tree need to trigger a close event.

@catmando
Copy link
Contributor Author

Agree... I think I will add a HyperEvent gem this week, and close this problem if it seem to fit the bill. See https://github.com/ruby-hyperloop/ruby-hyperloop.io/wiki/Keeping-Track-of-Multiple-Components (at the end) for example

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants