2011-08-30 13 views
6

voglio generare l'evento "nodo principale aperto" sul mio attuale CellTree di lavoro, che ora ha il seguente comportamento:Programatically aggiornare un 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; 
    } 

Come posso licenziare che "onRangeChanged" evento, al Aggiorna i miei nodi di livello 1?

Qual è il mio metodo di convenienza mancante?

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

risposta

2

I nodi di livello 1 (la media al di sotto del nodo principale suppongo) non può essere rinfrescato il modo in cui si sta facendo.

È necessario memorizzare l'istanza del dataProvider per i nodi di livello 1 da qualche parte. Successivamente, quando aggiorni l'elenco, devi aggiornare il tuo DataProvider salvato per i tuoi nodi di livello 1.
I nodi sotto il livello 1 possono essere aggiornati nel modo in cui lo si sta facendo. Perché non appena si chiudono i nodi di livello 1 (questo è ciò che si sta facendo nel metodo updateTree) e la prossima volta che lo si apre, viene chiamato getNodeInfo e le sottocategorie aggiornate verranno recuperate e visualizzate in CellTree.

UPDATE

Per rinfrescare le CellWidgets che è attaccato alla AsyncDataProvider probabilmente si dovrà estendere l'AsyncDataProvider e né estrarre la chiamata RPC a un metodo getData() che viene chiamato nel onRangeChanged() metodo o creare un interface with a refresh method e implementarlo nel proprio AsyncDataProvider personalizzato che chiama il metodo protetto onRangeChanged().

+0

<< Più tardi, quando si aggiorna l'elenco è necessario aggiornare la stored dataProvider per i nodi di livello-1. >> Bene!^___^ma ... COME?!? -.- 'Voglio dire, l'unico metodo disponibile sul provider è updateRowData(), devo duplicare il codice rpc presente in onRangeChanged(), o posso semplicemente attivare l'evento "range changed" in qualche modo ?? grazie –

+0

vedi la mia risposta aggiornata –

4

Esempio di lavoro. Aggiungi riferimento a DataProvider (e Nodo padre) (MyMenuItem e MyCell con DataProvider nel mio codice). Dopo aver aggiunto elemento aggiornamento genitore.

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


} 

nel modulo aggiungere

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