转换器与列表控制器调用两次

Converter called twice with list controller

I binded the selected item of a list with a label widget. I also added a converter to transform my data. Although the binding is unidrectionnal (http://www.qooxdoo.org/5.0.1/apiviewer/#qx.data.SingleValueBinding~bind), the converter seems to be called twice.

Here is a code snippet. Select any element in the list and check the browser's console.

Shoudln't it be called only once?

I also found this related thread on the Gitter chat. The user's problem is solved but it doesn't explain why the converter is called twice with a unidirectionnal binding : https://gitter.im/qooxdoo/qooxdoo?at=579b01dc1d6bf8244e2b5f71

This is a side effect of some very old code which is arguably a bug but which was quite possibly created for compatibility (we're talking about pre v1.x code here) and ease of use; the qx.data.controller.List will fire an additional "changeSelection" event when the selection changes. This sounds natural, until you consider that the selection property is an object and therefore the property List.selection is not changing at all - instead the contents of the selection array object are changing.

In your example, the binding is listening to 'selection[0]', which means that it has to listen to changes to List.selection as well as changes to the contents of the array in List.selection. Because there is the extra 'changeSelection' fired by qx.controller.List this causes the extra call to your converter.

In many circumstances the net effect of this is suppressed and not noticed, at least partly because bindings to other properties will detect that the value has already been set and therefore not fire twice; here's an alternative code snippet which listens to changes to the Label.value property, and in the console you can see that while the converter is fired twice, the Label.value property is only fired once.

I agree that it is a bug; I've filed it as an issue here but the problem is that because this is established behaviour, if we stop firing the changeSelection event, it is quite possible that will break existing applications and make the upgrade path much harder for existing users. Please feel free to join in the discussion on the issue to debate what the best way forward is.

Thanks for your complete answer. So, as an alternative, I can bind the whole selection to the label widget and use data.getItem(0)in the converter. This way, there's only one selectionchange event.
Yes - although you should be sure to check that the array is not empty before calling getItem(0) because qx.data.Array throws an exception if you try to get an element beyond the length of the array