jimsparkman / RiotControl

Event Controller / Dispatcher For RiotJS, Inspired By Flux
http://jimsparkman.github.io/RiotControl/routing_demo/
MIT License
598 stars 48 forks source link

RiotControl.on('eventName') appears to run twice per event fired as where Stores runs once which is desired behaviors. #7

Closed madwill closed 9 years ago

madwill commented 9 years ago

Hi

I'm trying out RiotJS and using shared dispatcher for prototyping. Its all very great and RiotJS al the most impressive views library I've had the chance to face yet.

My main problem is when triggering events from RiotControl.trigger onto a RiotControl.on events gets fired twice.

http://i.imgur.com/HVNJt6Q.png

https://gist.github.com/madwill/a320c0b8fc69c600ad04

When triggering an event that is only listened on a Store it gets fired once which is fine.

But when triggering from the store back to the view, then i get 2 events no matter what.

Is there anything i should know ?

Thanks

William

madwill commented 9 years ago

It appears it is related to the require() using webpack.

I'm up to 3 event on each trigger now.

ulrikstrid commented 9 years ago

This seems to happen even when using .one (using it in node).

jimsparkman commented 9 years ago

Do you have a minimal fiddle demo? And riotjs version #?

madwill commented 9 years ago

Hi

Riot version is 2.0.15, the latest one I've found.

It seems to be related to the number of store. I currently have 3 stores and have every event listened on the RiotControl object triggered 3 time, I had 2 when creating this ticket and had event being fired 2 times.

I don't think i can create a fiddle since it appears to be related to require.

If you create this setup add 2 stores and register them in index.js.

Then as my first comment gist send a "init" event to the store and have the store send something back. to app.tag which listen to whatever that is.

You'll get it twice and if you register 3 stores you'll get it 3 times.

ulrikstrid commented 9 years ago

Getting a feeling that my problem is with riot and not RiotControl

avanslaars commented 9 years ago

I'm seeing the same thing. The number of times an event is fired is directly tied to the number of stores in my application. Any resolution, workaround or identification of the root cause for this?

madwill commented 9 years ago

Personally I've never found one. Decided to go with PostalJS for pub sub of event. It has channels wich is nice.

Good luck

oderwat commented 9 years ago

After running into similar problems we actually found it is a bug in our code!

For us it was related to two things:

  1. Usage of "RiotControl.on()" from inside the store implementation.
  2. Not removing event handler (for unmounted tags in this case)

After fixing both problems everything worked as expected.

a-moses commented 9 years ago

@oderwat Please make new gist work file .

Thank You !

oderwat commented 9 years ago

I did. Hopefully it solves your problem, please report!

avanslaars commented 9 years ago

@a-moses - I don't understand your question.

oderwat commented 9 years ago

neither do I .. and I also did not get a reply to the proposed changes I made in his gist.

oderwat commented 9 years ago

@a-moses I wrote my comment into your gist. I am not going to create a new gist in my account to change one word in your pseudocode. Actually I unsubscribed this issue now. That Video discussion is pretty much off topic here.

jimsparkman commented 9 years ago

If there is an outstanding issue here, I should have some free time this weekend to review. Otherwise, it looks like it may have been usage related.

osiloke commented 9 years ago

Hi, still an issue. It seems, it only has one use. Manages events for one store. Something like this may solve this problem. It uses namespaces to route events to observables rather than stores.

var _RiotControlApi = ['on','one','off','trigger']
function Global(){
  Riot.observable(this)
}
var RiotControl = { 
  _namespace_delimeter: ':',
  _global: new Global(),
  _observers: {},

  addObserver: function(namespace, observer) {
    this._observers[namespace] = observer
  }, 
}

_RiotControlApi.forEach(function(api){
  RiotControl[api] = function() {
    var args = [].slice.call(arguments)
    var unsplit = args[0].split(this._namespace_delimeter)  
    try{
      this._observers[unsplit[0]][api].apply(null, args)
    }catch(e){ 
      this._global[api].apply(null, args)
    }
  }
})
a-moses commented 9 years ago

@oderwat Thank you about your comment.

Now the code work well done.

@oderwat @jimsparkman maybe some update to the documentation will minimize some of users issue .

luisvinicius167 commented 8 years ago

Great! I had the same problem!