Tuesday, August 26, 2008

PureMVC Gotcha

Don't send notifications that you're expecting a response to in your mediator's constructor (or during construction). Instead, override the onRegister() function and call them there. Your Mediator won't receive notifications it's interested in until after the registration process is finished. Seems pretty obvious, but you can loose track real quick of what's going on in the background when you're using a system like PureMVC that just seems to work.

Thursday, August 21, 2008

Crazy Flex DateField Insanity

So, I've been busily putting together a Flex application at work, and we ran into a curious issue where Flash would infinitely loop and crash itself/the browser. (Not tested in Air) To give a little background first, we're following the convention of keeping our data in data objects (or data models), and binding both the visual component to the data model field and the data model field back to the visual component. All of our code is dynamic, so it's written in Actionscript, not MXML.
The problem occurred when we had two DateField interface components pointing to the same data model field. The two DateFields would be hooked up to a single data model field, and we saw the following behavior:
  • If we bound the DateField.selectedDate to the model.birthday (as an example), with one DateField Instance, all would work. Underneath, it set off the bindings twice when you changed the selectedDate, but that was OK. With multiple DateField Instances, it would crash as it tried to create the second DateField. (This happened when we preinitialized the DateField and without preinitializing the DateField) Underneath, it would set off the bindings between the three items infinitely.
  • If we bound the DateField.data to the model.birthday, it would never infinitely loop, but model.birthday wouldn't get updated when DateField was changed. I think that the code for DateField.data is screwy, but according to the documentation, it seems like this is the property you should bind to.
  • If I tried binding the DateField.data to the model.birthday and the model.birthday to the DateField.selectedDate, it would also loop infinitely.
Finally, I created a ChangeWatcher on the DateField for when the selectedDate changed. On change, it would call a function that checked to see if DateField.data == DateField.selectedDate, and if not, it set DateField.data = DateField.selectedDate. At first, this didn't work quite right, but I changed it to check the DateField.data.time, which is just the number of seconds since Epoch, and that magically worked.

My theory is that Date comparisons are broken or behave oddly, and if you just compare Date.time, it works as expected. I'm assuming this is why the binding went forever, but I can't be sure.

Hope this helps someone else.. some also possibly helpful links: