BorisMoore / jsviews

Interactive data-driven views, MVVM and MVP, built on top of JsRender templates
http://www.jsviews.com/#jsviews
MIT License
857 stars 130 forks source link

Delay in updating of property in datalinked checkbox #320

Closed markibanez closed 9 years ago

markibanez commented 9 years ago

Hi @BorisMoore,

I had a weird issue using a datalinked checkbox. Here's my HTML

<label class="user-access"><input type="checkbox" data-link="{:ManageForms trigger=true:} disabled{:IsOwner} onchange{:'UpdateTenantUserAccess(' + TenantID + ',' + UserID + ')'}" /> Manage Forms</label>

So what happened was the UpdateTenantUserAccess function was picking up the old value of the property ManageForms bound to the checkbox. I had to enclose my code in a setTimeout to allow the datalink to "catch up" and get the proper value.

While enclosing code in a setTimeout isn't a hassle, I just feels hacky and inelegant. Am I doing something wrong here? Is there a way to fix this without using setTimeout?

BorisMoore commented 9 years ago

To be honest, that seems a strange approach. You are dynamically updating the onchange property of the input, and having two handlers for the onChange event - the DOM level 0 handler that you are setting (UpdateTenantUserAccess) and the data-link="{:ManageForms trigger=true:} handler.

You are attaching two separate listeners to the onChange event, so you will need to control sequencing between those two event handlers. Which of them is 'in charge'. In what order will they fire?

I would try to avoid DOM level 0 handlers and only have one onChange hander. You can use convert and convertback handlers: data-link="{cvt:ManageForms trigger=true:cvtBack}" - so the UpdateTenantUserAccess code could probably go into a cvtBack converter.

Alternatively, rather than using cvtBack, you can simply drive your UpdateTenantUserAccess using $.observe() or $.observeAll() event listener to listen to relevant data changes, including ManageForms property, and calling your Update... code. It is generally cleaner to have UI update data, and data then drive UI and application state etc...

markibanez commented 9 years ago

Oh I didn't realize that the data-link created an event handler. Yes, I agree that observe event listener is the best way to do it. Thanks

BorisMoore commented 9 years ago

@markibanez: You might be interested in these - perhaps related/useful for your scenario:

http://jsfiddle.net/BorisMoore/hqy06tm5/ https://github.com/BorisMoore/jsviews/issues/311#issuecomment-143846808