Uploaded image for project: 'ZK'
  1. ZK
  2. ZK-4211

listbox selection causes invalidate

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 8.5.2.1, 8.6.0.1
    • Fix Version/s: 8.6.2
    • Component/s: Databind 2
    • Security Level: Jean
    • Labels:
      None
    • gh.sprint.customfield.default.name:
      ZK 8.6.2 S1, ZK 8.6.2 S2

      Description

      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

        Attachments

          Activity

            People

            • Assignee:
              DevChu DevChu
              Reporter:
              cor3000 cor3000
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: