Thank you for reporting this bug. We will make it our priority to review this report.
  1. #1
    Sencha User
    Join Date
    Jul 2011
    Posts
    11
    Vote Rating
    0
    BerndM is on a distinguished road

      0  

    Default TreeGrid & ListStore.update()

    TreeGrid & ListStore.update()


    GXT Beta 4.0

    Description:
    Create a TreeGrid with a ListStore containing several elements (A,B,C..). Create a new element X with the same id as A and call ListStore.update(X). Add a new element Y as child of X (ListStore.add(X, Y)). The new element Y isn't rendered.

    Findings:
    I investigated this behaviour and I think the reason might be that the model of the TreeNode isn't updated properly after store.update() has been called. The TreeGridView requires the correct reference in order to find the Dom Elements.

    The code segment in TreeGrid:

    Code:
      protected void onUpdate(StoreUpdateEvent<M> se) {
        for (M m : se.getItems()) {
          store.update(m);
        }
      }
    should be something like:

    Code:
      protected void onUpdate(StoreUpdateEvent<M> se) {
        for (M m : se.getItems()) {
    TreeGridNode<M> node = (TreeGridNode<M>)findNode(m);
          if (node.model != m) { // see Tree
             node.model = m;
          }
          store.update(m);
        }
      }
    unfortunately I couldn't test it because node.model is private and I cannot acces it.
    would be great if you could have a look at it.

    Thanks,
    Bernd

  2. #2
    Sencha User
    Join Date
    Jul 2011
    Posts
    11
    Vote Rating
    0
    BerndM is on a distinguished road

      0  

    Default


    I was able to fix the bug through deriving from TreeGrid. (a bit hacky, but works)
    Code below (TreeElement is my model type):

    Code:
    public class TreeElementTreeGrid extends TreeGrid<TreeElement> {
        
         public static class TreeGridNode2 extends TreeGridNode<TreeElement> {
            TreeElement model;
             
            protected TreeGridNode2(String id, TreeElement m) {
                super(id, null);
                this.model = m;
            }
                 
             public TreeElement getModel() {
                  return model;
             }
                 
              public void setModel(TreeElement model) {
                  this.model = model;
              }
         }
        
        public TreeElementTreeGrid(TreeStore<TreeElement> store, ColumnModel<TreeElement> cm,
                ColumnConfig<TreeElement, ?> treeColumn) {
            super(store, cm, treeColumn);
        }
        
      protected String register(TreeElement m) {
        String id = generateModelId(m);
        if (!nodes.containsKey(id)) {
          nodes.put(id, new TreeGridNode2(id, m));
        }
        return id;
      }
      
        protected void onUpdate(StoreUpdateEvent<TreeElement> se) {
            for (TreeElement m : se.getItems()) {
                TreeGridNode2 node = (TreeGridNode2)findNode(m);
                node.setModel(m);
            }
            super.onUpdate(se);
        }
        
    }

  3. #3
    Sencha User
    Join Date
    Jul 2011
    Posts
    11
    Vote Rating
    0
    BerndM is on a distinguished road

      0  

    Default


    I wrote a quick example which demonstrates the problem.
    Click Button 1, Click Button 2, try to expand / collapse the tree node.

    Code:
        class A {
            public String id;
            public String folder;
            
            public A(String id, String folder) {
                this.id = id;
                this.folder = folder;
            }
        }
        
        /**
         * This is the entry point method.
         */
        public void onModuleLoad() {
            
            ColumnConfig<A, String> cc1 = new ColumnConfig<A, String>(
                    new ValueProvider<A, String>() {
    
                        @Override
                        public String getValue(A object) {
                            return object.folder;
                        }
    
                        @Override
                        public void setValue(A object, String value) {
                            object.folder = value;
                        }
    
                        @Override
                        public String getPath() {
                            return "folder";
                        }
                    }, 220, "Folder");
            
            List<ColumnConfig<A, ?>> l = new ArrayList<ColumnConfig<A, ?>>();
            l.add(cc1);
            
            ColumnModel<A> cm = new ColumnModel<A>(l);
            
            final TreeStore<A> ts = new TreeStore<A>(new ModelKeyProvider<A>() {
    
                @Override
                public String getKey(A item) {
                    return item.id;
                }
            });
            
            A[] a = {
                    new A("1", "Folder 1"), 
                    new A("2", "Folder 2"), 
                    new A("3", "Folder 3"),
                    new A("4", "Folder 4"),
                    new A("5", "Folder 5")
            };
            
            ts.add(a[0]);
            ts.add(a[1]);
            ts.add(a[0], a[2]);
            ts.add(a[0], a[3]);
            ts.add(a[0], a[4]);
            
            final TreeGrid<A> tg = new TreeGrid<A>(ts, cm, cc1);
            tg.setSize("200px", "200px");
            
            final A x = new A("1", "New Folder Name");
            
            TextButton update = new TextButton("1. update ListStore");
            update.addSelectHandler(new SelectHandler() {
                
                @Override
                public void onSelect(SelectEvent event) {
                    ts.update(x);
                }
            });
            
            TextButton add = new TextButton("2. add child to ListStore");
            add.addSelectHandler(new SelectHandler() {
                
                @Override
                public void onSelect(SelectEvent event) {
                    ts.add(x, new A("6", "Child Folder"));
                }
            });
                    
            VerticalLayoutContainer c = new VerticalLayoutContainer();
            c.add(tg);
            c.add(update);
            c.add(add);
            
            RootPanel.get().add(c);
        }