2011-08-30 26 views
6

chcę odpalić „węzła głównego otwarte” wydarzenie w moim obecnym CellTree roboczego, który ma teraz następujące zachowanie:Programowo odświeżyć GWT CellTree

@Override 
    public <T> NodeInfo<?> getNodeInfo(final T value) { 
     return new DefaultNodeInfo<Categoria>(
       (value instanceof Categoria) ? 
         createBranchDataProvider((Categoria)value) : 
         rootDataProvider, 
       new CategoriaCell() 
     ); 
    } 

private AsyncDataProvider<Categoria> createRootDataProvider() { 
     AsyncDataProvider<Categoria> dataProvider = new AsyncDataProvider<Categoria>() { 
      @Override 
      protected void onRangeChanged(HasData<Categoria> display) { 
       AsyncCallback<Categoria[]> cb = new AsyncCallback<Categoria[]>() { 
        @Override 
        public void onSuccess(Categoria[] result) { 
         updateRowCount(result.length, true); 
         updateRowData(0, Arrays.asList(result)); 
        } 
        @Override 
        public void onFailure(Throwable caught) { 
         Window.alert(caught.toString()); 
        } 
       }; 
       rpcService.getCategorie(cb); 
      } 
     }; 
     return dataProvider; 
    } 

Jak mogę pożar, który „onRangeChanged” zdarzenie, aby odświeżyć moje węzły poziomu 1?

Jaka jest moja metoda nieobecności?

private void updateTree() {  
     TreeNode rootTreeNode = cellTree.getRootTreeNode(); 
     for (int i = 0; i < rootTreeNode.getChildCount(); i++) { 
      rootTreeNode.setChildOpen(i, false); 
     } 
     // HOW TO REFRESH LEVEL-1 NODES? 
    } 

Odpowiedz

2

poziomie-1 węzłów (Przypuszczam, że średnia poniżej węzła głównego) nie mogą być odświeżane sposób to robią.

Musisz przechowywać wystąpienie swojego providera danych dla węzłów poziomu 1 gdzieś. Później, po odświeżeniu listy, musisz zaktualizować przechowywany element dataProvider dla swoich węzłów poziomu 1.
Węzły poniżej poziomu 1 można odświeżać tak, jak to robisz. Ponieważ, gdy tylko zamkniesz węzły poziomu 1 (to jest to, co robisz w metodzie updateTree) i następnym razem je otworzysz, zostanie wywołane getNodeInfo, a zaktualizowane podkategorie zostaną pobrane i wyświetlone w CellTree.

UPDATE

odświeżania CellWidgets które jest dołączone do AsyncDataProvider prawdopodobnie będzie musiał przedłużyć AsyncDataProvider i albo wyodrębnić wywołanie RPC do getData() metody, która jest wywoływana w onRangeChanged() metoda lub utworzyć interface with a refresh method i zaimplementuj go w niestandardowym AsyncDataProvider, który wywołuje metodę protected onRangeChanged().

+0

<< Później po odświeżeniu listy trzeba zaktualizować zapisany dataProvider na swój poziom-1 węzłów. >> Dobry!^___^ale ... JAK?!? -.- "Chodzi mi o to, że jedyną dostępną metodą dla dostawcy jest updateRowData(), czy muszę zduplikować kod rpc obecny w onRangeChanged(), czy mogę po prostu wywołać w jakiś sposób zdarzenie" range changed "? dzięki –

+0

zobacz moją zaktualizowaną odpowiedź –

4

Przykład roboczy. Dodaj odwołanie do DataProvider (i węzła nadrzędnego) (MyMenuItem i MyCell with DataProvider w moim kodzie). Po dodaniu elementu odświeżającego elementu nadrzędnego.

public class MyMenuItem { 
    private String name; 
    private String action; //some data 
    private int level; //if needed 
    private ArrayList<MyMenuItem> list; //nodes childrens 
    private MyMenuItem parent; //track internal parent 
    private MyCell cell; //for refresh - reference to visual component 

    public void setCell(MyCell cell) { 
     this.cell = cell; 
    } 
    public void refresh() { 
     if(parent!=null) { 
      parent.refresh(); 
     } 
     if (cell!=null) { 
      cell.refresh(); //refresh tree 
     } 
    } 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
    public String getAction() { 
     return action; 
    } 
    public void setAction(String action) { 
     this.action = action; 
    } 
    public MyMenuItem(String name, String action) { 
     super(); 
     parent = null; 
     level = 0; 
     this.name = name; 
     this.action = action; 
     list = new ArrayList<MyMenuItem>(); 
    } 
    public MyMenuItem(String name) { 
     this(name, ""); 
    } 
    public void addSubMenu(MyMenuItem m) { 
     m.level = this.level+1; 
     m.parent = this; 
     list.add(m); 
    } 

    public boolean hasChildrens() { 
     return list.size()>0; 
    } 
    public int getLevel() { 
     return level; 
    } 
    public void setLevel(int level) { 
     this.level = level; 
    } 
    public ArrayList<MyMenuItem> getList() { 
     return list; 
    } 
    public MyMenuItem getParent() { 
     return parent; 
    } 
} 

public class MyTreeModel implements TreeViewModel { 
    private MyMenuItem officialRoot; //default not dynamic 
    private MyMenuItem studentRoot; //default not dynamic 
    private MyMenuItem testRoot; //default not dynamic 
    private MyMenuItem root; 

    public MyMenuItem getRoot() { // to set CellTree root 
     return root; 
    } 

    public MyTreeModel() { 
     root = new MyMenuItem("root"); 
     // Default items 
     officialRoot = new MyMenuItem("Official"); //some basic static data 
     studentRoot = new MyMenuItem("Student"); 
     testRoot = new MyMenuItem("Test"); 
     root.addSubMenu(officialRoot); 
     root.addSubMenu(studentRoot); 
     root.addSubMenu(testRoot); 
    } 

    //example of add add logic 
    private void addNew(MyMenuItem myparent, String name, String uid) { 
     myparent.addSubMenu(new MyMenuItem(name, uid)); 
     myparent.refresh(); //HERE refresh tree 
    } 

    @Override 
    public <T> NodeInfo<?> getNodeInfo(T value) { 
     ListDataProvider<MyMenuItem> dataProvider; 
     MyMenuItem myValue = null; 
     if (value == null) { // root is not set 
      dataProvider = new ListDataProvider<MyMenuItem>(root.getList()); 
     } else { 
      myValue = (MyMenuItem) value; 
      dataProvider = new ListDataProvider<MyMenuItem>(myValue.getList()); 
     } 
     MyCell cell = new MyCell(dataProvider); //HERE Add reference 
     if (myValue != null) 
      myValue.setCell(cell); 
     return new DefaultNodeInfo<MyMenuItem>(dataProvider, cell); 
    } 

    @Override 
    public boolean isLeaf(Object value) { 
     if (value instanceof MyMenuItem) { 
      MyMenuItem t = (MyMenuItem) value; 
      if (!t.hasChildrens()) 
       return true; 
      return false; 
     } 
     return false; 
    } 

} 

public class MyCell extends AbstractCell<MyMenuItem> { 
     ListDataProvider<MyMenuItem> dataProvider; //for refresh 
     public MyCell(ListDataProvider<MyMenuItem> dataProvider) { 
      super("keydown","dblclick"); 
      this.dataProvider = dataProvider; 
     } 
     public void refresh() { 
      dataProvider.refresh(); 
     } 
     @Override 
     public void onBrowserEvent(Context context, Element parent, MyMenuItem value, 
      NativeEvent event, ValueUpdater<MyMenuItem> valueUpdater) { 
      if (value == null) { 
      return; 
      } 
      super.onBrowserEvent(context, parent, value, event, valueUpdater); 
      if ("click".equals(event.getType())) { 
      this.onEnterKeyDown(context, parent, value, event, valueUpdater); 
      } 
      if ("dblclick".equals(event.getType())) { 
       this.onEnterKeyDown(context, parent, value, event, valueUpdater); 
      } 
     } 

     @Override 
     public void render(Context context, MyMenuItem value, SafeHtmlBuilder sb) { 
      if (value == null) { 
      return; 
      } 
      sb.appendEscaped(value.getName()); 
      //add HERE for better formating 
     } 


     @Override 
     protected void onEnterKeyDown(Context context, Element parent, 
       MyMenuItem value, NativeEvent event, ValueUpdater<MyMenuItem> valueUpdater) { 
      Window.alert("You clicked "+event.getType()+" " + value.getName()); 
     } 


} 

w module dodać

treeModel = new MyTreeModel(); 
tree = new CellTree(treeModel,treeModel.getRoot());