dalgard / meteor-viewmodel

Minimalist VM for Meteor
24 stars 2 forks source link

Binding twice after reconnect #20

Open KoenLav opened 8 years ago

KoenLav commented 8 years ago

Hi Kristian,

We are happily using your package for a while now. But since a while it seems that events are binded to HTML nodes twice after Meteor reconnects.

Have you seen this problem before?

Where is the code located which binds the event (within your package)? Maybe I can take a look ;)

dalgard commented 8 years ago

:+1:

KoenLav commented 8 years ago

I wish I could create a test case, but I have yet to be able to reproduce this in any other setting...

I'm going to try to 'cut out' the code causing this, but to be honest I expect it would just start working when I isolate it (going to try to do so anyway).

dalgard commented 8 years ago

Try wrapping the bind passed to onReady (inside the Nexus constructor) like you've done above, and have it output to console.log, too – and then add the nexus selector to that log as well as the rest of them – what do you get?

// Bind element on view ready
this.onReady(() => {
  // What does Meteor.checkElement mean, btw?
  console.log("onReady", this.selector);

  this.bind();
});
dalgard commented 8 years ago

In other words, does unbind seem to run before bind for the same selector?

KoenLav commented 8 years ago

I use the checkElement function to filter the console.logs to just one element.

KoenLav commented 8 years ago

First rendering of the element:

click: addProduct viewmodel.js:510 ===== viewmodel.js:512 newNexus nexus.js:120 ===== 2base.js:81 onViewReady nexus.js:113 onReady [vm-bind-id='128'] nexus.js:261 bind

Destroing of the element (caused by reconnect): onDestroyed [vm-bind-id='128'] nexus.js:275 unbind nexus.js:311 true

Second rendering of the element (caused by reconnect):

click: addProduct viewmodel.js:510 ===== viewmodel.js:512 newNexus nexus.js:120 ===== nexus.js:103 onDestroyed [vm-bind-id='259'] nexus.js:275 unbind nexus.js:311 false base.js:66 afterFlush nexus.js:113 onReady [vm-bind-id='259'] nexus.js:261 bind viewmodel.js:483 click: addProduct viewmodel.js:510 ===== viewmodel.js:512 newNexus nexus.js:120 ===== base.js:66 afterFlush nexus.js:113 onReady [vm-bind-id='287'] nexus.js:261 bind

So you are right, the unbind on 259 is called before the bind is called.

dalgard commented 8 years ago

Just as I suspected. Interesting...

KoenLav commented 8 years ago

Terribly sorry, I made a mistake in the copying of the console.logs, it's not the onDestroyed callback causing this, it's the onInvalidate (which makes much, much more sense).

dalgard commented 8 years ago

Right. Still...

KoenLav commented 8 years ago

Ok, I think I've written a fix.

I will be cleaning up my code and verifying whether it works in multiple scenario's.

KoenLav commented 8 years ago

I submitted a pull request, I had to hurry a little so it is not thoroughly tested, but the basic idea should be clear:

When a view becomes ready, we set viewModelReady to true.

If we invalidate the view, it is no longer ready. When we then try to invalidate it again, we move the unbinding to the onReady.