-
Bug
-
Resolution: Fixed
-
Major
-
8.5.2.1, 8.6.0.1
-
Security Level: Jean
-
None
-
ZK 8.6.2 S1, ZK 8.6.2 S2
-
None
Steps to Reproduce
1) run listbox-selection-binding.zul -> "aaa", "bbb" are already pre-selected (but could be selected manually causing the same issue)
2) select listitem "ccc"
3) unselect any listitem
Current Result
step 3) causes a call to listbox.invalidate() re-rendering all listitems
Expected Result
no need to re-render the listbox items when selection changes only
Debug Info
enabling the data bind logging shows a difference between a "normal" selection change and the one triggering the invalidate
normal one... only the selectedItem property is notified (expected)
======================================= [2858]ON_EVENT [2858] *[event] [onSelect] <listbox uuid="nXyP1" id="" /> [2858] + SAVE_BINDING [2858] *[save:prop-save] [event = onSelect] selectedItems > vm.selectedItems [aaa, bbb, ccc] <listbox uuid="nXyP1" id="" /> [2858]NOTIFY_CHANGE [2858] *[notify-change] [TestVm@63a21038][selectedItems] <div uuid="nXyP0" id="" /> Size=1 [2858] + LOAD_BINDING [2858] *[load:prop-load] vm.selectedItems > selectedItems [aaa, bbb, ccc] <listbox uuid="nXyP1" id="" /> *Converter.IGNORED_VALUE
when unselecting also the items property is notified even though it didn't change.
This eventually calls listbox.setModel() causing the invalidate
======================================= [2859]ON_EVENT [2859] *[event] [onSelect] <listbox uuid="nXyP1" id="" /> [2859] + SAVE_BINDING [2859] *[save:prop-save] [event = onSelect] selectedItems > vm.selectedItems [aaa, ccc] <listbox uuid="nXyP1" id="" /> [2859]NOTIFY_CHANGE [2859] *[notify-change] [TestVm@63a21038][selectedItems] <div uuid="nXyP0" id="" /> Size=2 [2859] + LOAD_BINDING [2859] *[load:prop-load] vm.selectedItems > selectedItems [aaa, ccc] <listbox uuid="nXyP1" id="" /> *Converter.IGNORED_VALUE [2859] + LOAD_BINDING [2859] *[load:prop-load] vm.items > model [aaa, bbb, ccc] <listbox uuid="nXyP1" id="" /> [2859]ON_EVENT [2859] *[event] [onAfterRender] <listbox uuid="nXyP1" id="" /> [2859] + LOAD_BINDING [2859] *[load:prop-load] [event = onAfterRender] vm.selectedItems > selectedItems [aaa, ccc] <listbox uuid="nXyP1" id="" /> *Converter.IGNORED_VALUE
Root Cause
Only if the selectedItems collection contains the same elements as items in the same order, the additional notify change is triggered.
E.g. selecting bbb, aaa, ccc and then unselecting any item doesn't cause the extra load binding.
It seems both collections are considered identical hence triggering both load bindings.
Workaround
Use a java.util.Set for selectedItems avoiding equality to a List