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

      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;
          }
      
      }
      

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

              Created:
              Updated:
              Resolved: