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

Property value is loaded twice when property binding and children binding are used together

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Normal
    • Resolution: Fixed
    • Affects Version/s: 7.0.3
    • Fix Version/s: 7.0.4
    • Component/s: Databind 2
    • Security Level: Jimmy

      Description

      Problem Description:

      If property binding is used inside children binding, then the bound property will be loaded twice, causing the corresponding getter to be invoked twice. This may affect the performance of the system.

      Steps to reproduce:

      1. Open 'mvvmPropertyChildrenBinding.zul'
      2. See the console message
      -> For each label, it is created only once, but getName() is called twice.
      3. Uncomment 'stack trace' code in the view model or Set a breakpoint in getName()
      4. Observe the stack trace

      mvvmPropertyChildrenBinding.zul
      <div apply="org.zkoss.bind.BindComposer"
          viewModel="@id('vm') @init('test.PropertyChildrenBindingViewModel')">
          <vlayout children="@load(vm.model)">
              <template name="children">
                  <label value="@init(each.name)">
                      <attribute name="onCreate">
                      System.out.println("label value=\"@init()\" created");
                      </attribute>
                  </label>
                  <label value="@load(each.name)">
                      <attribute name="onCreate">
                      System.out.println("label value=\"@load()\" created");
                      </attribute>
                  </label>
              </template>
          </vlayout>
      </div>
      
      PropertyChildrenBindingViewModel.java
      package test;
      
      import java.util.ArrayList;
      import java.util.List;
      
      import org.zkoss.bind.annotation.Init;
      
      public class PropertyChildrenBindingViewModel {
      
          public class Item {
              private final String name;
      
              public Item(String name) {
                  this.name = name;
              }
      
              public String getName() {
                  System.out.println("getName()");
      //          for (StackTraceElement elem : Thread.currentThread().getStackTrace())
      //              System.out.println(elem.toString());
      
                  return name;
              }
          }
      
          private List<Item> _model = new ArrayList<Item>();
          
          @Init
          public void init() {
              _model.add(new Item("test"));
          }
          
          public List<Item> getModel() {
              return _model;
          }
      
      }
      

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              jumperchen jumperchen
              Reporter:
              neillee neillee
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: